Logo ROOT   6.08/07
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 
36 TLDAPServer::TLDAPServer(const char *host, Int_t port, const char *binddn,
37  const char *password, Int_t version)
38 {
39  fLd = 0;
40  fIsConnected = kFALSE;
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) {
75  TObject::operator=(lds);
76  fLd=lds.fLd;
77  fBinddn=lds.fBinddn;
78  fPassword=lds.fPassword;
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 
250 TLDAPResult *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 
381 Int_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 
400 void 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 }
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.
TLDAPResult * GetAttributeTypes()
Calls GetSubschemaSubentry() and performs and LDAPSearch with the attribute "attributeTypes" to be re...
Collectable string class.
Definition: TObjString.h:32
return c
Bool_t IsConnected() const
Definition: TLDAPServer.h:51
const char * GetSubschemaSubentry()
Performs an LDAPSearch with the attribute "subschemaSubentry" to be returned with the result...
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
const char * GetNamingContexts()
Performs an LDAPSearch with the attribute "namingContexts" to be returned with the result...
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
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...
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:137
TLDAPResult * GetObjectClasses()
Calls GetSubschemaSubentry() and performs and LDAPSearch with the attribute "objectClasses" to be ret...
Bool_t fIsConnected
Definition: TLDAPServer.h:33
Int_t ModifyEntry(TLDAPEntry &entry, Int_t mode=LDAP_MOD_REPLACE)
Modifies specified entry.
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition: TObject.cxx:103
Int_t DeleteEntry(const char *dn)
Deletes the entry with specified DN, the base entry must exist.
void Error(const char *location, const char *msgfmt,...)
TLDAPAttribute * GetAttribute() const
Get next attribute of the entry.
Definition: TLDAPEntry.cxx:96
A doubly linked list.
Definition: TList.h:47
virtual ~TLDAPServer()
If the object is connected to the server, it disconnects.
Definition: TLDAPServer.cxx:86
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
LDAPMod ** GetMods(Int_t op)
Get array of "LDAPMod" structures for entry.
Definition: TLDAPEntry.cxx:185
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
TLDAPServer & operator=(const TLDAPServer &)
Equal operator.
Definition: TLDAPServer.cxx:72
TLDAPEntry * GetNext()
Returns next entry from the search result.
Definition: TLDAPResult.cxx:68
TString fPassword
Definition: TLDAPServer.h:32
#define ClassImp(name)
Definition: Rtypes.h:279
void Unbind()
Unbinds from the server with specified binddn and password.
static void DeleteMods(LDAPMod **mods)
Deletes the array of LDAPMod structures and frees its memory.
Mother of all ROOT objects.
Definition: TObject.h:37
TString fBinddn
Definition: TLDAPServer.h:31
Int_t Bind()
Binds to the server with specified binddn and password.
Definition: TLDAPServer.cxx:95
const char * GetDn() const
Definition: TLDAPEntry.h:49
LDAP * fLd
Definition: TLDAPServer.h:30
Int_t AddEntry(TLDAPEntry &entry)
Adds entry to the LDAP tree.
double result[121]
TLDAPServer(const TLDAPServer &)
Copy constructor.
Definition: TLDAPServer.cxx:60
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:416
virtual Int_t GetSize() const
Definition: TCollection.h:95
const Bool_t kTRUE
Definition: Rtypes.h:91
const Int_t n
Definition: legend1.C:16
const char * GetValue() const
Get next value of the attribute.
const char * Data() const
Definition: TString.h:349