Logo ROOT   6.16/01
Reference Guide
TLDAPServer.cxx
Go to the documentation of this file.
1// @(#)root/ldap:$Id$
2// Author: Oleksandr Grebenyuk 21/09/2001
3
4/*************************************************************************
5 * For the licensing terms see $ROOTSYS/LICENSE. *
6 * For the list of contributors see $ROOTSYS/README/CREDITS. *
7 *************************************************************************/
8
9#include "TLDAPServer.h"
10#include "TLDAPResult.h"
11#include "TLDAPEntry.h"
12#include "TLDAPAttribute.h"
13#include "TObjString.h"
14#include "TList.h"
15#include "TError.h"
16
17
19
20////////////////////////////////////////////////////////////////////////////////
21/// During construction TLDAPServer object tries to connect to the
22/// specified server and you should check the connection status by
23/// calling the IsConnected() member function immediately after
24/// creating that object.
25/// const char *host: The name of host to connect. Default is "localhost".
26/// Int_t port: Port number to connect. Default is LDAP_PORT (=389).
27/// const char *binddn: Bind DN.
28/// const char *password: Password. Usually you have to specify bind DN and
29/// password to have the write permissions. Default
30/// values for bind DN and password are zero, that means
31/// anonymous connection. Usually it is enough to read
32/// the data from the server.
33/// Int_t version Set LDAP protocol version: LDAP_VERSION1,
34/// LDAP_VERSION2, LDAP_VERSION3
35
36TLDAPServer::TLDAPServer(const char *host, Int_t port, const char *binddn,
37 const char *password, Int_t version)
38{
39 fLd = 0;
41 fBinddn = binddn;
42 fPassword = password;
43
44 fLd = ldap_init(host, port);
45 if (!fLd) {
46 Error("TLDAPServer", "error in ldap_init function");
47 } else {
48 if (ldap_set_option(fLd, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS ) {
49 Error("Bind", "Could not set protocol version!");
50 return;
51 }
52
53 Bind( );
54 }
55}
56
57////////////////////////////////////////////////////////////////////////////////
58/// Copy constructor
59
61 TObject(lds),
62 fLd(lds.fLd),
63 fBinddn(lds.fBinddn),
64 fPassword(lds.fPassword),
65 fIsConnected(lds.fIsConnected)
66{
67}
68
69////////////////////////////////////////////////////////////////////////////////
70/// Equal operator
71
73{
74 if(this!=&lds) {
76 fLd=lds.fLd;
77 fBinddn=lds.fBinddn;
80 } return *this;
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// If the object is connected to the server, it disconnects.
85
87{
88 Unbind();
89}
90
91////////////////////////////////////////////////////////////////////////////////
92/// Binds to the server with specified binddn and password.
93/// Return value: LDAP error code, 0 if successfully bound.
94
96{
97 if (!IsConnected()) {
98 Int_t result = ldap_simple_bind_s(fLd, fBinddn.Data(), fPassword.Data());
99 if (result != LDAP_SUCCESS) {
100 ldap_unbind(fLd);
102 switch (result) {
103 case LDAP_INVALID_CREDENTIALS:
104 Error("Bind", "invalid password");
105 break;
106 case LDAP_INAPPROPRIATE_AUTH:
107 Error("Bind", "entry has no password to check");
108 break;
109 default :
110 Error("Bind", "%s", ldap_err2string(result));
111 break;
112 }
113 } else {
115 }
116 return result;
117 }
118 return 0;
119}
120
121////////////////////////////////////////////////////////////////////////////////
122/// Unbinds from the server with specified binddn and password.
123
125{
126 if (IsConnected()) {
127 ldap_unbind(fLd);
129 }
130}
131
132////////////////////////////////////////////////////////////////////////////////
133/// Performs an LDAPSearch with the attribute "namingContexts" to be
134/// returned with the result. The value of this attribute is
135/// extracted and returned as const char.
136
138{
139 TList *attrs = new TList;
140 attrs->SetOwner();
141 attrs->AddLast(new TObjString("namingContexts"));
142 const char *namingcontexts = 0;
143
144 TLDAPResult *result = Search("", LDAP_SCOPE_BASE, 0, attrs, 0);
145
146 if (result) {
147 TLDAPEntry *entry = result->GetNext();
148 if (entry) {
149 TLDAPAttribute *attribute = entry->GetAttribute();
150 if (attribute)
151 namingcontexts = attribute->GetValue();
152 delete entry;
153 }
154 delete result;
155 }
156 delete attrs;
157
158 return namingcontexts;
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Performs an LDAPSearch with the attribute "subschemaSubentry" to
163/// be returned with the result. The value of this attribute is
164/// extracted and returned as const char.
165
167{
168 TList *attrs = new TList;
169 attrs->SetOwner();
170 attrs->AddLast(new TObjString("subschemaSubentry"));
171 const char *subschema = 0;
172
173 TLDAPResult *result = Search("", LDAP_SCOPE_BASE, 0, attrs, 0);
174
175 if (result) {
176 TLDAPEntry *entry = result->GetNext();
177 if (entry) {
178 TLDAPAttribute *attribute = entry->GetAttribute();
179 if (attribute)
180 subschema = attribute->GetValue();
181 delete entry;
182 }
183 delete result;
184 }
185 delete attrs;
186
187 return subschema;
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Calls GetSubschemaSubentry() and performs and LDAPSearch with
192/// the attribute "objectClasses" to be returned with the result.
193/// The returned result object must be deleted by the user.
194
196{
197 const char *subschema = GetSubschemaSubentry();
198
199 TList *attrs = new TList;
200 attrs->SetOwner();
201 attrs->AddLast(new TObjString("objectClasses"));
202
203 TLDAPResult *result = Search(subschema, LDAP_SCOPE_BASE, 0, attrs, 0);
204
205 delete attrs;
206
207 return result;
208}
209
210////////////////////////////////////////////////////////////////////////////////
211/// Calls GetSubschemaSubentry() and performs and LDAPSearch with the
212/// attribute "attributeTypes" to be returned with the result.
213/// The returned result object must be deleted by the user.
214
216{
217 const char *subschema = GetSubschemaSubentry();
218
219 TList *attrs = new TList;
220 attrs->SetOwner();
221 attrs->AddLast(new TObjString("attributeTypes"));
222
223 TLDAPResult *result = Search(subschema, LDAP_SCOPE_BASE, 0, attrs, 0);
224
225 delete attrs;
226
227 return result;
228}
229
230////////////////////////////////////////////////////////////////////////////////
231/// Performs searching at the LDAP directory.
232/// Return value: a TLDAPResult object or 0 in case of error.
233/// Result needs to be deleted by user.
234/// const char *base: Specifies the base object for the search operation
235/// Int_t scope: Specifies the portion of the LDAP tree, relative to
236/// the base object, to search.
237/// Must be one of LDAP_SCOPE_BASE (==0),
238/// LDAP_SCOPE_ONELEVEL (==1) or LDAP_SCOPE_SUBTREE (==2).
239/// char *filter: The criteria during the search to determine which
240/// entries to return, 0 means that the filter
241/// "(objectclass=*)" will be applied
242/// TList *attrs: The TList of attributes to be returned along with
243/// each entry, 0 means that all available attributes
244/// should be returned.
245/// Int_t attrsonly: This parameter is a boolean specifying whether both
246/// types and values should be returned with each
247/// attribute (zero) or types only should be returned
248/// (non-zero).
249
250TLDAPResult *TLDAPServer::Search(const char *base, Int_t scope,
251 const char *filter, TList *attrs,
252 Bool_t attrsonly)
253{
254 Bind();
255
256 Int_t errcode;
257 TLDAPResult *result = 0;
258
259 if (IsConnected()) {
260
261 LDAPMessage *searchresult;
262 char **attrslist = 0;
263 if (attrs) {
264 Int_t n = attrs->GetSize();
265 attrslist = new char* [n + 1];
266 for (Int_t i = 0; i < n; i++)
267 attrslist[i] = (char*) ((TObjString*)attrs->At(i))->GetName();
268 attrslist[n] = 0;
269 }
270 if (filter == 0)
271 filter = "(objectClass=*)";
272
273 errcode = ldap_search_s(fLd, base, scope, filter, attrslist,
274 attrsonly, &searchresult);
275
276 delete [] attrslist;
277
278 if (errcode == LDAP_SUCCESS) {
279 result = new TLDAPResult(fLd, searchresult);
280 } else {
281 ldap_msgfree(searchresult);
282 Error("Search", "%s", ldap_err2string(errcode));
283 }
284
285 } else {
286 errcode = LDAP_SERVER_DOWN;
287 Error("Search", "%s", "server is not connected");
288 }
289
290 return result;
291}
292
293////////////////////////////////////////////////////////////////////////////////
294/// Adds entry to the LDAP tree.
295/// Be sure that you are bound with write permissions.
296/// Return value: LDAP error code.
297
299{
300 Bind();
301
302 Int_t errcode;
303 if (IsConnected()) {
304 LDAPMod **ms = entry.GetMods(0);
305 errcode = ldap_add_s(fLd, entry.GetDn(), ms);
307 if (errcode != LDAP_SUCCESS)
308 Error("AddEntry", "%s", ldap_err2string(errcode));
309 } else {
310 errcode = LDAP_SERVER_DOWN;
311 Error("AddEntry", "server is not connected");
312 }
313 return errcode;
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Modifies specified entry.
318/// Be sure that you are bound with write permissions.
319/// Return value: LDAP error code, 0 = success.
320/// TLDAPEntry &entry: Entry to be modified.
321/// Int_t mode: Modifying mode.
322/// Should be one of LDAP_MOD_ADD (==0),
323/// LDAP_MOD_DELETE (==1) or LDAP_MOD_REPLACE (==2)
324/// Specifies what to do with all the entry's attributes
325/// and its values - add to the corresponding entry on
326/// the server, delete from it, or replace the
327/// corresponding attributes with new values
328
330{
331 Bind();
332
333 Int_t errcode;
334 if (IsConnected()) {
335 LDAPMod **ms = entry.GetMods(mode);
336 errcode = ldap_modify_s(fLd, entry.GetDn(), ms);
338 if (errcode != LDAP_SUCCESS)
339 Error("ModifyEntry", "%s", ldap_err2string(errcode));
340 } else {
341 errcode = LDAP_SERVER_DOWN;
342 Error("ModifyEntry", "server is not connected");
343 }
344 return errcode;
345}
346
347////////////////////////////////////////////////////////////////////////////////
348/// Deletes the entry with specified DN, the base entry must exist.
349/// Be sure that you are bound with write permissions.
350/// Return value: LDAP error code, 0 = succes.
351
353{
354 Bind();
355
356 Int_t errcode;
357 if (IsConnected()) {
358 errcode = ldap_delete_s(fLd, dn);
359 if (errcode != LDAP_SUCCESS)
360 Error("DeleteEntry", "%s", ldap_err2string(errcode));
361 } else {
362 errcode = LDAP_SERVER_DOWN;
363 Error("DeleteEntry", "server is not connected");
364 }
365 return errcode;
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Renames the entry with specified DN, the entry must be leaf
370/// Be sure that you are bound with the write permissions
371/// Return value: LDAP error code, 0 = succes
372/// char *dn: Distinguished name of entry to be renamed.
373/// This entry must be a leaf in the LDAP directory tree.
374/// char *newrdn: The new relative distinguished name to give the entry
375/// being renamed.
376/// Bool_t removeattr: This parameter specifies whether or not the
377/// attribute values in the old relative distinguished
378/// name should be removed from the entry
379/// or retained as non-distinguished attributes.
380
381Int_t TLDAPServer::RenameEntry(const char *dn, const char *newrdn, Bool_t removeattr)
382{
383 Int_t errcode;
384 if (IsConnected()) {
385 errcode = ldap_modrdn2_s(fLd, dn, newrdn, removeattr);
386 if (errcode != LDAP_SUCCESS)
387 Error( "RenameEntry", "%s", ldap_err2string(errcode));
388 } else {
389 errcode = LDAP_SERVER_DOWN;
390 Error("RenameEntry", "server is not connected");
391 }
392 return errcode;
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Deletes the array of LDAPMod structures and frees its memory.
397/// LDAPMod **mods: Pointer to the zero-terminated array of pointers
398/// to LDAPMod structures
399
400void TLDAPServer::DeleteMods(LDAPMod **mods)
401{
402#if 1
403 ldap_mods_free(mods, 1);
404#else
405 Int_t i = 0;
406 LDAPMod *mod;
407 while ((mod = mods[i++]) != 0) {
408 if (mod->mod_op & LDAP_MOD_BVALUES) {
409 ber_bvecfree(mod->mod_bvalues);
410 } else {
411 Int_t j = 0;
412 char *c;
413 while ((c = mod->mod_values[j++]) != 0)
414 delete c;
415 }
416 delete mod->mod_type;
417 delete mod;
418 }
419 delete mods;
420#endif
421}
#define c(i)
Definition: RSha256.hxx:101
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
const char * GetValue() const
Get next value of the attribute.
TLDAPAttribute * GetAttribute() const
Get next attribute of the entry.
Definition: TLDAPEntry.cxx:96
LDAPMod ** GetMods(Int_t op)
Get array of "LDAPMod" structures for entry.
Definition: TLDAPEntry.cxx:185
const char * GetDn() const
Definition: TLDAPEntry.h:41
TLDAPEntry * GetNext()
Returns next entry from the search result.
Definition: TLDAPResult.cxx:68
LDAP * fLd
Definition: TLDAPServer.h:24
virtual ~TLDAPServer()
If the object is connected to the server, it disconnects.
Definition: TLDAPServer.cxx:86
Int_t ModifyEntry(TLDAPEntry &entry, Int_t mode=LDAP_MOD_REPLACE)
Modifies specified entry.
TLDAPResult * GetAttributeTypes()
Calls GetSubschemaSubentry() and performs and LDAPSearch with the attribute "attributeTypes" to be re...
TString fPassword
Definition: TLDAPServer.h:26
Bool_t IsConnected() const
Definition: TLDAPServer.h:45
TLDAPResult * GetObjectClasses()
Calls GetSubschemaSubentry() and performs and LDAPSearch with the attribute "objectClasses" to be ret...
const char * GetSubschemaSubentry()
Performs an LDAPSearch with the attribute "subschemaSubentry" to be returned with the result.
TString fBinddn
Definition: TLDAPServer.h:25
Bool_t fIsConnected
Definition: TLDAPServer.h:27
TLDAPServer(const TLDAPServer &)
Copy constructor.
Definition: TLDAPServer.cxx:60
void Unbind()
Unbinds from the server with specified binddn and password.
TLDAPResult * Search(const char *base="", Int_t scope=LDAP_SCOPE_BASE, const char *filter=0, TList *attrs=0, Bool_t attrsonly=0)
Performs searching at the LDAP directory.
static void DeleteMods(LDAPMod **mods)
Deletes the array of LDAPMod structures and frees its memory.
Int_t AddEntry(TLDAPEntry &entry)
Adds entry to the LDAP tree.
Int_t RenameEntry(const char *dn, const char *newrdn, Bool_t removeattr=kFALSE)
Renames the entry with specified DN, the entry must be leaf Be sure that you are bound with the write...
const char * GetNamingContexts()
Performs an LDAPSearch with the attribute "namingContexts" to be returned with the result.
TLDAPServer & operator=(const TLDAPServer &)
Equal operator.
Definition: TLDAPServer.cxx:72
Int_t DeleteEntry(const char *dn)
Deletes the entry with specified DN, the base entry must exist.
Int_t Bind()
Binds to the server with specified binddn and password.
Definition: TLDAPServer.cxx:95
A doubly linked list.
Definition: TList.h:44
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:149
Collectable string class.
Definition: TObjString.h:28
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.h:271
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
const char * Data() const
Definition: TString.h:364
const Int_t n
Definition: legend1.C:16
static constexpr double ms