4 * Lightweight Directory Access Protocol interface class.
6 * Portable Windows Library
8 * Copyright (c) 1993-2003 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Contributor(s): ______________________________________.
27 * Revision 1.23 2007/09/08 11:34:28 rjongbloed
28 * Improved memory checking (leaks etc), especially when using MSVC debug library.
30 * Revision 1.22 2007/07/19 15:05:36 shorne
31 * Added Factory loaded LDAP schemas
33 * Revision 1.21 2007/04/20 07:23:53 csoutheren
34 * Applied 1703646 - Fixed behaviour of PLDAPSession::GetSearchResult
35 * Thanks to Fabrizio Ammollo
37 * Revision 1.20 2006/01/16 19:52:05 dsandras
38 * Applied patch from Brian Lu <brian lu sun com> to allow compilation on
39 * Solaris using SUN's LDAP. Thanks!!
41 * Revision 1.19 2005/09/18 13:01:43 dominance
42 * fixed pragma warnings when building with gcc.
44 * Revision 1.18 2005/08/31 15:21:34 dominance
45 * fix building with recent OpenLDAP
47 * Revision 1.17 2004/05/24 12:02:49 csoutheren
48 * Add function to permit setting a limit on the number of results returned
49 * from an LDAP query. Change the default number of results to unlimited,
50 * rather than MAX_INT which apparently is clamped to some arbitrary low value.
51 * Thanks to Damien Sandras
53 * Revision 1.16 2004/04/09 06:52:17 rjongbloed
54 * Removed #pargma linker command for /delayload of DLL as documentations sais that
57 * Revision 1.15 2004/02/23 23:52:19 csoutheren
58 * Added pragmas to avoid every Windows application needing to include libs explicitly
60 * Revision 1.14 2004/02/04 09:37:00 rjongbloed
61 * Fixed memory leak and race condition, thanks Rossano Ravelli
63 * Revision 1.13 2004/01/17 17:45:29 csoutheren
64 * Changed to use PString::MakeEmpty
66 * Revision 1.12 2003/07/15 12:12:11 csoutheren
67 * Added support for multiple values in a single attribute string
68 * Thanks to Ravelli Rossano
70 * Revision 1.11 2003/07/12 00:10:40 csoutheren
71 * Fixed problem where Modify routines were calling Add, thanks to Ravelli Rossano
73 * Revision 1.10 2003/06/06 09:14:01 dsandras
75 * Test that a search result has been returned before calling ldapresult2error.
77 * Revision 1.9 2003/06/05 23:17:52 rjongbloed
78 * Changed default operation timeout to 30 seconds.
80 * Revision 1.8 2003/06/05 05:29:30 rjongbloed
81 * Fixed LDAP bind authentication methods, thanks Ravelli Rossano
83 * Revision 1.7 2003/04/17 08:34:48 robertj
84 * Changed LDAP structure output so if field is empty it leaves it out
85 * altogether rather then encoding an empty string, some servers barf.
87 * Revision 1.6 2003/04/16 08:00:19 robertj
88 * Windoes psuedo autoconf support
90 * Revision 1.5 2003/04/07 11:59:52 robertj
91 * Fixed search function returning an error if can't find anything for filter.
93 * Revision 1.4 2003/04/01 07:05:16 robertj
94 * Added ability to specify host:port in opening an LDAP server
96 * Revision 1.3 2003/03/31 03:32:53 robertj
97 * Major addition of functionality.
102 #pragma implementation "pldap.h"
107 #include <ptlib/sockets.h>
108 #include <ptclib/pldap.h>
115 #define LDAP_DEPRECATED 1
119 #if defined(_MSC_VER)
120 #pragma comment(lib, P_LDAP_LIBRARY)
123 ///////////////////////////////////////////////////////////////////////////////
125 PLDAPSession::PLDAPSession(const PString
& baseDN
)
127 errorNumber(LDAP_SUCCESS
),
128 protocolVersion(LDAP_VERSION3
),
129 defaultBaseDN(baseDN
),
132 multipleValueSeparator('\n')
137 PLDAPSession::~PLDAPSession()
143 BOOL
PLDAPSession::Open(const PString
& server
, WORD port
)
147 PString host
= server
;
148 PINDEX colon
= server
.Find(':');
149 if (colon
!= P_MAX_INDEX
) {
150 host
= server
.Left(colon
);
151 port
= PIPSocket::GetPortByService(server
.Mid(colon
+1), "tcp");
154 ldapContext
= ldap_init(server
, port
);
158 SetOption(LDAP_OPT_PROTOCOL_VERSION
, protocolVersion
);
163 BOOL
PLDAPSession::Close()
168 ldap_unbind(ldapContext
);
174 BOOL
PLDAPSession::SetOption(int optcode
, int value
)
179 return ldap_set_option(ldapContext
, optcode
, &value
);
183 BOOL
PLDAPSession::SetOption(int optcode
, void * value
)
188 return ldap_set_option(ldapContext
, optcode
, value
);
192 BOOL
PLDAPSession::Bind(const PString
& who
,
193 const PString
& passwd
,
194 AuthenticationMethod authMethod
)
206 static const int AuthMethodCode
[NumAuthenticationMethod2
] = {
207 LDAP_AUTH_SIMPLE
, LDAP_AUTH_SASL
, LDAP_AUTH_KRBV41_30
, LDAP_AUTH_KRBV42_30
209 static const int AuthMethodCode
[NumAuthenticationMethod
] = {
210 LDAP_AUTH_SIMPLE
, LDAP_AUTH_SASL
, LDAP_AUTH_KRBV4
213 errorNumber
= ldap_bind_s(ldapContext
, whoPtr
, passwd
, AuthMethodCode
[authMethod
]);
214 return errorNumber
== LDAP_SUCCESS
;
218 PLDAPSession::ModAttrib::ModAttrib(const PString
& n
, Operation o
)
225 void PLDAPSession::ModAttrib::SetLDAPMod(struct ldapmod
& mod
, Operation defaultOp
)
227 mod
.mod_type
= (char *)(const char *)name
;
229 Operation realOp
= op
== NumOperations
? defaultOp
: op
;
230 static const int OpCode
[NumOperations
] = {
231 LDAP_MOD_ADD
, LDAP_MOD_REPLACE
, LDAP_MOD_DELETE
233 mod
.mod_op
= OpCode
[realOp
];
236 mod
.mod_op
|= LDAP_MOD_BVALUES
;
242 PLDAPSession::StringModAttrib::StringModAttrib(const PString
& name
,
244 : ModAttrib(name
, op
)
249 PLDAPSession::StringModAttrib::StringModAttrib(const PString
& name
,
250 const PString
& value
,
252 : ModAttrib(name
, op
)
258 PLDAPSession::StringModAttrib::StringModAttrib(const PString
& name
,
259 const PStringList
& vals
,
261 : ModAttrib(name
, op
),
267 void PLDAPSession::StringModAttrib::SetValue(const PString
& value
)
270 values
.AppendString(value
);
274 void PLDAPSession::StringModAttrib::AddValue(const PString
& value
)
276 values
.AppendString(value
);
280 BOOL
PLDAPSession::StringModAttrib::IsBinary() const
286 void PLDAPSession::StringModAttrib::SetLDAPModVars(struct ldapmod
& mod
)
288 pointers
.SetSize(values
.GetSize()+1);
290 for (i
= 0; i
< values
.GetSize(); i
++)
291 pointers
[i
] = values
[i
].GetPointer();
293 mod
.mod_values
= pointers
.GetPointer();
297 PLDAPSession::BinaryModAttrib::BinaryModAttrib(const PString
& name
,
299 : ModAttrib(name
, op
)
304 PLDAPSession::BinaryModAttrib::BinaryModAttrib(const PString
& name
,
305 const PBYTEArray
& value
,
307 : ModAttrib(name
, op
)
313 PLDAPSession::BinaryModAttrib::BinaryModAttrib(const PString
& name
,
314 const PList
<PBYTEArray
> & vals
,
316 : ModAttrib(name
, op
),
322 void PLDAPSession::BinaryModAttrib::SetValue(const PBYTEArray
& value
)
325 values
.Append(new PBYTEArray(value
));
329 void PLDAPSession::BinaryModAttrib::AddValue(const PBYTEArray
& value
)
331 values
.Append(new PBYTEArray(value
));
335 BOOL
PLDAPSession::BinaryModAttrib::IsBinary() const
341 void PLDAPSession::BinaryModAttrib::SetLDAPModVars(struct ldapmod
& mod
)
343 pointers
.SetSize(values
.GetSize()+1);
344 bervals
.SetSize(values
.GetSize()*sizeof(berval
));
345 berval
* ber
= (berval
*)bervals
.GetPointer();
347 for (i
= 0; i
< values
.GetSize(); i
++) {
348 ber
[i
].bv_val
= (char *)values
[i
].GetPointer();
349 ber
[i
].bv_len
= values
[i
].GetSize();
350 pointers
[i
] = &ber
[i
];
353 mod
.mod_bvalues
= pointers
.GetPointer();
357 static LDAPMod
** CreateLDAPModArray(const PList
<PLDAPSession::ModAttrib
> & attributes
,
358 PLDAPSession::ModAttrib::Operation defaultOp
,
359 PBYTEArray
& storage
)
361 PINDEX count
= attributes
.GetSize();
362 storage
.SetSize(count
*sizeof(LDAPMod
) + (count
+1)*sizeof(LDAPMod
*));
364 LDAPMod
** attrs
= (LDAPMod
**)storage
.GetPointer();
365 LDAPMod
* attr
= (LDAPMod
* )&attrs
[count
+1];
366 for (PINDEX i
= 0; i
< count
; i
++) {
368 attributes
[i
].SetLDAPMod(attr
[i
], defaultOp
);
375 static PList
<PLDAPSession::ModAttrib
> AttribsFromDict(const PStringToString
& attributes
)
377 PList
<PLDAPSession::ModAttrib
> attrs
;
379 for (PINDEX i
= 0; i
< attributes
.GetSize(); i
++)
380 attrs
.Append(new PLDAPSession::StringModAttrib(attributes
.GetKeyAt(i
),
381 attributes
.GetDataAt(i
).Lines()));
387 static PList
<PLDAPSession::ModAttrib
> AttribsFromArray(const PStringArray
& attributes
)
389 PList
<PLDAPSession::ModAttrib
> attrs
;
391 for (PINDEX i
= 0; i
< attributes
.GetSize(); i
++) {
392 PString attr
= attributes
[i
];
393 PINDEX equal
= attr
.Find('=');
394 if (equal
!= P_MAX_INDEX
)
395 attrs
.Append(new PLDAPSession::StringModAttrib(attr
.Left(equal
),
396 attr
.Mid(equal
+1).Lines()));
403 static PList
<PLDAPSession::ModAttrib
> AttribsFromStruct(const PLDAPStructBase
& attributes
)
405 PList
<PLDAPSession::ModAttrib
> attrs
;
407 for (PINDEX i
= 0; i
< attributes
.GetNumAttributes(); i
++) {
408 PLDAPAttributeBase
& attr
= attributes
.GetAttribute(i
);
410 attrs
.Append(new PLDAPSession::BinaryModAttrib(attr
.GetName(), attr
.ToBinary()));
412 PString str
= attr
.ToString();
414 attrs
.Append(new PLDAPSession::StringModAttrib(attr
.GetName(), str
));
422 BOOL
PLDAPSession::Add(const PString
& dn
, const PList
<ModAttrib
> & attributes
)
429 errorNumber
= ldap_add_ext(ldapContext
,
431 CreateLDAPModArray(attributes
, ModAttrib::Add
, storage
),
435 if (errorNumber
!= LDAP_SUCCESS
)
438 P_timeval tval
= timeout
;
439 LDAPMessage
* result
= NULL
;
440 ldap_result(ldapContext
, msgid
, LDAP_MSG_ALL
, tval
, &result
);
442 errorNumber
= ldap_result2error(ldapContext
, result
, TRUE
);
444 return errorNumber
== LDAP_SUCCESS
;
448 BOOL
PLDAPSession::Add(const PString
& dn
, const PStringToString
& attributes
)
450 return Add(dn
, AttribsFromDict(attributes
));
454 BOOL
PLDAPSession::Add(const PString
& dn
, const PStringArray
& attributes
)
456 return Add(dn
, AttribsFromArray(attributes
));
460 BOOL
PLDAPSession::Add(const PString
& dn
, const PLDAPStructBase
& attributes
)
462 return Add(dn
, AttribsFromStruct(attributes
));
466 BOOL
PLDAPSession::Modify(const PString
& dn
, const PList
<ModAttrib
> & attributes
)
473 errorNumber
= ldap_modify_ext(ldapContext
,
475 CreateLDAPModArray(attributes
, ModAttrib::Replace
, storage
),
479 if (errorNumber
!= LDAP_SUCCESS
)
482 P_timeval tval
= timeout
;
483 LDAPMessage
* result
= NULL
;
484 ldap_result(ldapContext
, msgid
, LDAP_MSG_ALL
, tval
, &result
);
486 errorNumber
= ldap_result2error(ldapContext
, result
, TRUE
);
488 return errorNumber
== LDAP_SUCCESS
;
492 BOOL
PLDAPSession::Modify(const PString
& dn
, const PStringToString
& attributes
)
494 return Modify(dn
, AttribsFromDict(attributes
));
498 BOOL
PLDAPSession::Modify(const PString
& dn
, const PStringArray
& attributes
)
500 return Modify(dn
, AttribsFromArray(attributes
));
504 BOOL
PLDAPSession::Modify(const PString
& dn
, const PLDAPStructBase
& attributes
)
506 return Modify(dn
, AttribsFromStruct(attributes
));
510 BOOL
PLDAPSession::Delete(const PString
& dn
)
516 errorNumber
= ldap_delete_ext(ldapContext
, dn
, NULL
, NULL
, &msgid
);
517 if (errorNumber
!= LDAP_SUCCESS
)
520 P_timeval tval
= timeout
;
521 LDAPMessage
* result
= NULL
;
522 ldap_result(ldapContext
, msgid
, LDAP_MSG_ALL
, tval
, &result
);
524 errorNumber
= ldap_result2error(ldapContext
, result
, TRUE
);
526 return errorNumber
== LDAP_SUCCESS
;
530 PLDAPSession::SearchContext::SearchContext()
539 PLDAPSession::SearchContext::~SearchContext()
542 ldap_msgfree(message
);
544 if (result
!= NULL
&& result
!= message
)
545 ldap_msgfree(result
);
549 BOOL
PLDAPSession::Search(SearchContext
& context
,
550 const PString
& filter
,
551 const PStringArray
& attributes
,
552 const PString
& baseDN
,
559 char ** attribs
= attributes
.ToCharArray(&storage
);
561 PString base
= baseDN
;
563 base
= defaultBaseDN
;
565 static const int ScopeCode
[NumSearchScope
] = {
566 LDAP_SCOPE_BASE
, LDAP_SCOPE_ONELEVEL
, LDAP_SCOPE_SUBTREE
569 P_timeval tval
= timeout
;
571 errorNumber
= ldap_search_ext(ldapContext
,
583 if (errorNumber
!= LDAP_SUCCESS
)
586 if (ldap_result(ldapContext
, context
.msgid
, LDAP_MSG_ONE
, tval
, &context
.result
) > 0)
587 return GetNextSearchResult(context
);
590 errorNumber
= ldap_result2error(ldapContext
, context
.result
, TRUE
);
591 if (errorNumber
== 0)
592 errorNumber
= LDAP_OTHER
;
597 BOOL
PLDAPSession::GetSearchResult(SearchContext
& context
, PStringToString
& data
)
604 if (context
.result
== NULL
|| context
.message
== NULL
|| context
.completed
)
607 // Extract the resulting data
609 data
.SetAt("dn", GetSearchResultDN(context
));
611 BerElement
* ber
= NULL
;
612 char * attrib
= ldap_first_attribute(ldapContext
, context
.message
, &ber
);
613 while (attrib
!= NULL
) {
615 struct berval
** bvals
= ldap_get_values_len(ldapContext
, context
.message
, attrib
);
617 PString value
= data(attrib
);
619 for (PINDEX i
= 0; bvals
[i
] != NULL
; i
++ ) {
621 value
+= multipleValueSeparator
;
622 value
+= PString(bvals
[i
]->bv_val
, bvals
[i
]->bv_len
);
626 data
.SetAt(attrib
, value
);
629 ldap_memfree(attrib
);
630 attrib
= ldap_next_attribute(ldapContext
, context
.message
, ber
);
640 BOOL
PLDAPSession::GetSearchResult(SearchContext
& context
,
641 const PString
& attribute
,
649 if (context
.result
== NULL
|| context
.message
== NULL
|| context
.completed
)
652 if (attribute
== "dn") {
653 data
= GetSearchResultDN(context
);
657 char ** values
= ldap_get_values(ldapContext
, context
.message
, attribute
);
661 PINDEX count
= ldap_count_values(values
);
662 for (PINDEX i
= 0; i
< count
; i
++) {
664 data
+= multipleValueSeparator
;
668 ldap_value_free(values
);
673 BOOL
PLDAPSession::GetSearchResult(SearchContext
& context
,
674 const PString
& attribute
,
682 if (context
.result
== NULL
|| context
.message
== NULL
|| context
.completed
)
685 if (attribute
== "dn") {
687 data
[0] = GetSearchResultDN(context
);
691 char ** values
= ldap_get_values(ldapContext
, context
.message
, attribute
);
695 PINDEX count
= ldap_count_values(values
);
697 for (PINDEX i
= 0; i
< count
; i
++)
700 ldap_value_free(values
);
705 BOOL
PLDAPSession::GetSearchResult(SearchContext
& context
,
706 const PString
& attribute
,
707 PArray
<PBYTEArray
> & data
)
714 if (attribute
== "dn") {
715 char * dn
= ldap_get_dn(ldapContext
, context
.message
);
716 data
.Append(new PBYTEArray((const BYTE
*)dn
, ::strlen(dn
)));
721 struct berval
** values
= ldap_get_values_len(ldapContext
, context
.message
, attribute
);
725 PINDEX count
= ldap_count_values_len(values
);
727 for (PINDEX i
= 0; i
< count
; i
++) {
728 PBYTEArray
* dataPtr
= new PBYTEArray(values
[i
]->bv_len
);
729 data
.SetAt(i
, dataPtr
);
731 memcpy(data
[i
].GetPointer(), (const BYTE
*)values
[i
]->bv_val
, values
[i
]->bv_len
);
734 ldap_value_free_len(values
);
739 BOOL
PLDAPSession::GetSearchResult(SearchContext
& context
,
740 PLDAPStructBase
& data
)
745 BOOL atLeastOne
= FALSE
;
747 for (PINDEX i
= 0; i
< data
.GetNumAttributes(); i
++) {
748 PLDAPAttributeBase
& attr
= data
.GetAttribute(i
);
749 if (attr
.IsBinary()) {
750 PArray
<PBYTEArray
> bin
;
751 if (GetSearchResult(context
, attr
.GetName(), bin
)) {
752 attr
.FromBinary(bin
);
758 if (GetSearchResult(context
, attr
.GetName(), str
)) {
759 attr
.FromString(str
);
769 PString
PLDAPSession::GetSearchResultDN(SearchContext
& context
)
773 if (context
.message
!= NULL
) {
774 char * dn
= ldap_get_dn(ldapContext
, context
.message
);
785 BOOL
PLDAPSession::GetNextSearchResult(SearchContext
& context
)
790 if (context
.result
== NULL
|| context
.completed
)
793 P_timeval tval
= timeout
;
795 if (context
.message
== NULL
)
796 context
.message
= ldap_first_message(ldapContext
, context
.result
);
798 context
.message
= ldap_next_message(ldapContext
, context
.message
);
800 if (context
.message
!= NULL
) {
801 switch (ldap_msgtype(context
.message
)) {
802 case LDAP_RES_SEARCH_ENTRY
:
803 context
.found
= TRUE
;
804 errorNumber
= LDAP_SUCCESS
;
807 case LDAP_RES_SEARCH_RESULT
:
808 errorNumber
= ldap_result2error(ldapContext
, context
.message
, FALSE
);
809 if (errorNumber
== 0 && !context
.found
)
810 errorNumber
= LDAP_NO_RESULTS_RETURNED
;
811 context
.completed
= TRUE
;
814 // Ignore other result message types for now ...
817 ldap_msgfree(context
.result
);
818 } while (ldap_result(ldapContext
, context
.msgid
, LDAP_MSG_ONE
, tval
, &context
.result
) > 0);
821 errorNumber
= ldap_result2error(ldapContext
, context
.result
, FALSE
);
822 if (errorNumber
== 0)
823 errorNumber
= LDAP_OTHER
;
828 PList
<PStringToString
> PLDAPSession::Search(const PString
& filter
,
829 const PStringArray
& attributes
,
830 const PString
& base
,
833 PList
<PStringToString
> data
;
835 SearchContext context
;
836 if (!Search(context
, filter
, attributes
, base
, scope
))
840 PStringToString
* entry
= new PStringToString
;
841 if (GetSearchResult(context
, *entry
))
847 } while (GetNextSearchResult(context
));
853 PString
PLDAPSession::GetErrorText() const
855 return ldap_err2string(errorNumber
);
859 ///////////////////////////////////////////////////////////////////////////////
861 PLDAPAttributeBase::PLDAPAttributeBase(const char * n
, void * ptr
, PINDEX sz
)
866 PLDAPStructBase::GetInitialiser().AddAttribute(this);
870 PString
PLDAPAttributeBase::ToString() const
872 PStringStream stream
;
878 void PLDAPAttributeBase::FromString(const PString
& str
)
880 PStringStream
stream(str
);
885 PBYTEArray
PLDAPAttributeBase::ToBinary() const
887 return PBYTEArray((const BYTE
*)pointer
, size
, FALSE
);
891 void PLDAPAttributeBase::FromBinary(const PArray
<PBYTEArray
> & data
)
893 if (data
.GetSize() > 0 && data
[0].GetSize() == size
)
894 memcpy(pointer
, data
[0], size
);
898 ///////////////////////////////////////////////////////////////////////////////
900 PMutex
PLDAPStructBase::initialiserMutex
;
901 PLDAPStructBase
* PLDAPStructBase::initialiserInstance
;
903 PLDAPStructBase::PLDAPStructBase()
905 attributes
.DisallowDeleteObjects();
907 initialiserMutex
.Wait();
908 initialiserStack
= initialiserInstance
;
909 initialiserInstance
= this;
913 PLDAPStructBase
& PLDAPStructBase::operator=(const PLDAPStructBase
& other
)
915 for (PINDEX i
= 0; i
< attributes
.GetSize(); i
++)
916 attributes
.GetDataAt(i
).Copy(other
.attributes
.GetDataAt(i
));
922 PLDAPStructBase
& PLDAPStructBase::operator=(const PStringArray
& array
)
924 for (PINDEX i
= 0; i
< array
.GetSize(); i
++) {
925 PString str
= array
[i
];
926 PINDEX equal
= str
.Find('=');
927 if (equal
!= P_MAX_INDEX
) {
928 PLDAPAttributeBase
* attr
= GetAttribute(str
.Left(equal
));
930 attr
->FromString(str
.Mid(equal
+1));
937 PLDAPStructBase
& PLDAPStructBase::operator=(const PStringToString
& dict
)
939 for (PINDEX i
= 0; i
< dict
.GetSize(); i
++) {
940 PLDAPAttributeBase
* attr
= GetAttribute(dict
.GetKeyAt(i
));
942 attr
->FromString(dict
.GetDataAt(i
));
948 void PLDAPStructBase::PrintOn(ostream
& strm
) const
950 strm
<< attributes
<< '\n';
954 void PLDAPStructBase::AddAttribute(PLDAPAttributeBase
* attr
)
956 attributes
.SetAt(attr
->GetName(), attr
);
960 void PLDAPStructBase::EndConstructor()
962 initialiserInstance
= initialiserStack
;
963 initialiserMutex
.Signal();
966 ///////////////////////////////////////////////////////////////////
968 static const char PLDAPSchemaPluginBaseClass
[] = "PLDAPSchema";
970 template <> PLDAPSchema
* PDevicePluginFactory
<PLDAPSchema
>::Worker::Create(const PString
& type
) const
972 return PLDAPSchema::CreateSchema(type
);
975 PLDAPSchema::PLDAPSchema()
979 PLDAPSchema::Attribute::Attribute(const PString
& name
, AttributeType type
)
980 : m_name(name
),m_type(type
)
984 void PLDAPSchema::LoadSchema()
986 AttributeList(attributelist
);
989 PLDAPSchema
* PLDAPSchema::CreateSchema(const PString
& schemaname
, PPluginManager
* pluginMgr
)
991 if (pluginMgr
== NULL
)
992 pluginMgr
= &PPluginManager::GetPluginManager();
994 return (PLDAPSchema
*)pluginMgr
->CreatePluginsDeviceByName(schemaname
, PLDAPSchemaPluginBaseClass
);
997 PStringList
PLDAPSchema::GetSchemaNames(PPluginManager
* pluginMgr
)
999 if (pluginMgr
== NULL
)
1000 pluginMgr
= &PPluginManager::GetPluginManager();
1002 return pluginMgr
->GetPluginsProviding(PLDAPSchemaPluginBaseClass
);
1005 PStringList
PLDAPSchema::GetSchemaFriendlyNames(const PString
& schema
, PPluginManager
* pluginMgr
)
1007 if (pluginMgr
== NULL
)
1008 pluginMgr
= &PPluginManager::GetPluginManager();
1010 return pluginMgr
->GetPluginsDeviceNames(schema
, PLDAPSchemaPluginBaseClass
);
1013 void PLDAPSchema::OnReceivedAttribute(const PString
& attribute
, const PString
& value
)
1015 SetAttribute(attribute
,value
);
1018 BOOL
PLDAPSchema::SetAttribute(const PString
& attribute
, const PString
& value
)
1021 for (std::list
<Attribute
>::const_iterator r
= attributelist
.begin(); r
!= attributelist
.end(); ++r
) {
1022 if ((r
->m_name
== attribute
) && (r
->m_type
!= AttributeBinary
)) {
1023 attributes
.insert(make_pair(attribute
,value
));
1024 PTRACE(4, "schema\tMatch " << attribute
);
1032 BOOL
PLDAPSchema::SetAttribute(const PString
& attribute
, const PBYTEArray
& value
)
1034 for (std::list
<Attribute
>::const_iterator r
= attributelist
.begin(); r
!= attributelist
.end(); ++r
) {
1035 if ((r
->m_name
== attribute
) && (r
->m_type
== AttributeBinary
)) {
1036 binattributes
.insert(make_pair(attribute
,value
));
1037 PTRACE(4, "schema\tMatch Binary " << attribute
);
1045 BOOL
PLDAPSchema::GetAttribute(const PString
& attribute
, PString
& value
)
1047 for (ldapAttributes::const_iterator r
= attributes
.begin(); r
!= attributes
.end(); ++r
) {
1048 if (r
->first
== attribute
) {
1056 BOOL
PLDAPSchema::GetAttribute(const PString
& attribute
, PBYTEArray
& value
)
1058 for (ldapBinAttributes::const_iterator r
= binattributes
.begin(); r
!= binattributes
.end(); ++r
) {
1059 if (r
->first
== attribute
) {
1067 PStringList
PLDAPSchema::GetAttributeList()
1070 for (std::list
<Attribute
>::iterator r
= attributelist
.begin(); r
!= attributelist
.end(); ++r
) {
1071 att
.AppendString(r
->m_name
);
1076 BOOL
PLDAPSchema::Exists(const PString
& attribute
)
1078 for (std::list
<Attribute
>::const_iterator r
= attributelist
.begin(); r
!= attributelist
.end(); ++r
) {
1079 if (r
->m_name
== attribute
) {
1080 if (r
->m_type
== AttributeString
) {
1081 for (ldapAttributes::const_iterator r
= attributes
.begin(); r
!= attributes
.end(); ++r
) {
1082 if (r
->first
== attribute
)
1085 } else if (r
->m_type
== AttributeBinary
) {
1086 for (ldapBinAttributes::const_iterator r
= binattributes
.begin(); r
!= binattributes
.end(); ++r
) {
1087 if (r
->first
== attribute
)
1096 PLDAPSchema::AttributeType
PLDAPSchema::GetAttributeType(const PString
& attribute
)
1098 for (std::list
<Attribute
>::const_iterator r
= attributelist
.begin(); r
!= attributelist
.end(); ++r
) {
1099 if (r
->m_name
== attribute
)
1100 return (AttributeType
)r
->m_type
;
1102 return AttibuteUnknown
;
1105 void PLDAPSchema::OnSendSchema(PList
<PLDAPSession::ModAttrib
> & attrib
, PLDAPSession::ModAttrib::Operation op
)
1107 for (ldapAttributes::const_iterator r
= attributes
.begin(); r
!= attributes
.end(); ++r
)
1108 attrib
.Append(new PLDAPSession::StringModAttrib(r
->first
,r
->second
,op
));
1110 for (ldapBinAttributes::const_iterator s
= binattributes
.begin(); s
!= binattributes
.end(); ++s
) {
1111 attrib
.Append(new PLDAPSession::BinaryModAttrib(s
->first
,s
->second
,op
));
1119 // End of file ////////////////////////////////////////////////////////////////