TLDAPServer.cxx

Go to the documentation of this file.
00001 // @(#)root/ldap:$Id: TLDAPServer.cxx 34279 2010-07-01 11:02:15Z rdm $
00002 // Author: Oleksandr Grebenyuk   21/09/2001
00003 
00004 /*************************************************************************
00005  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00006  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00007  *************************************************************************/
00008 
00009 #include "TLDAPServer.h"
00010 #include "TLDAPResult.h"
00011 #include "TLDAPEntry.h"
00012 #include "TLDAPAttribute.h"
00013 #include "TObjString.h"
00014 #include "TList.h"
00015 #include "TError.h"
00016 
00017 
00018 ClassImp(TLDAPServer)
00019 
00020 //______________________________________________________________________________
00021 TLDAPServer::TLDAPServer(const char *host, Int_t port, const char *binddn,
00022                          const char *password, Int_t version)
00023 {
00024    // During construction TLDAPServer object tries to connect to the
00025    // specified server and you should check the connection status by
00026    // calling the IsConnected() member function immediately after
00027    // creating that object.
00028    // const char *host:     The name of host to connect. Default is "localhost".
00029    // Int_t port:           Port number to connect. Default is LDAP_PORT (=389).
00030    // const char *binddn:   Bind DN.
00031    // const char *password: Password. Usually you have to specify bind DN and
00032    //                       password to have the write permissions. Default
00033    //                       values for bind DN and password are zero, that means
00034    //                       anonymous connection. Usually it is enough to read
00035    //                       the data from the server.
00036    //  Int_t version        Set LDAP protocol version: LDAP_VERSION1,
00037    //                       LDAP_VERSION2, LDAP_VERSION3
00038 
00039    fLd          = 0;
00040    fIsConnected = kFALSE;
00041    fBinddn      = binddn;
00042    fPassword    = password;
00043 
00044    fLd = ldap_init(host, port);
00045    if (!fLd) {
00046       Error("TLDAPServer", "error in ldap_init function");
00047    } else {
00048       if (ldap_set_option(fLd, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS ) {
00049          Error("Bind", "Could not set protocol version!");
00050          return;
00051       }
00052 
00053       Bind( );
00054    }
00055 }
00056 
00057 //______________________________________________________________________________
00058 TLDAPServer::TLDAPServer(const TLDAPServer& lds) :
00059    TObject(lds),
00060    fLd(lds.fLd),
00061    fBinddn(lds.fBinddn),
00062    fPassword(lds.fPassword),
00063    fIsConnected(lds.fIsConnected)
00064 {
00065    // Copy constructor
00066 }
00067 
00068 //______________________________________________________________________________
00069 TLDAPServer& TLDAPServer::operator=(const TLDAPServer& lds)
00070 {
00071    // Equal operator
00072    if(this!=&lds) {
00073       TObject::operator=(lds);
00074       fLd=lds.fLd;
00075       fBinddn=lds.fBinddn;
00076       fPassword=lds.fPassword;
00077       fIsConnected=lds.fIsConnected;
00078    } return *this;
00079 }
00080 
00081 //______________________________________________________________________________
00082 TLDAPServer::~TLDAPServer()
00083 {
00084    // If the object is connected to the server, it disconnects.
00085 
00086    Unbind();
00087 }
00088 
00089 //______________________________________________________________________________
00090 Int_t TLDAPServer::Bind()
00091 {
00092    // Binds to the server with specified binddn and password.
00093    // Return value: LDAP error code, 0 if successfully bound.
00094 
00095    if (!IsConnected()) {
00096       Int_t result = ldap_simple_bind_s(fLd, fBinddn.Data(), fPassword.Data());
00097       if (result != LDAP_SUCCESS) {
00098          ldap_unbind(fLd);
00099          fIsConnected = kFALSE;
00100          switch (result) {
00101             case LDAP_INVALID_CREDENTIALS:
00102                Error("Bind", "invalid password");
00103                break;
00104             case LDAP_INAPPROPRIATE_AUTH:
00105                Error("Bind", "entry has no password to check");
00106                break;
00107             default :
00108                Error("Bind", "%s", ldap_err2string(result));
00109                break;
00110          }
00111       } else {
00112          fIsConnected = kTRUE;
00113       }
00114       return result;
00115    }
00116    return 0;
00117 }
00118 
00119 //______________________________________________________________________________
00120 void TLDAPServer::Unbind()
00121 {
00122    // Unbinds from the server with specified binddn and password.
00123 
00124    if (IsConnected()) {
00125       ldap_unbind(fLd);
00126       fIsConnected = kFALSE;
00127    }
00128 }
00129 
00130 //______________________________________________________________________________
00131 const char *TLDAPServer::GetNamingContexts()
00132 {
00133    // Performs an LDAPSearch with the attribute "namingContexts" to be
00134    // returned with the result. The value of this attribute is
00135    // extracted and returned as const char.
00136 
00137    TList *attrs = new TList;
00138    attrs->SetOwner();
00139    attrs->AddLast(new TObjString("namingContexts"));
00140 
00141    TLDAPResult *result = Search("", LDAP_SCOPE_BASE, 0, attrs, 0);
00142 
00143    TLDAPEntry *entry = result->GetNext();
00144 
00145    TLDAPAttribute *attribute = entry->GetAttribute();
00146 
00147    const char *namingcontexts = attribute->GetValue();
00148 
00149    delete entry;
00150    delete result;
00151    delete attrs;
00152 
00153    return namingcontexts;
00154 }
00155 
00156 //______________________________________________________________________________
00157 const char *TLDAPServer::GetSubschemaSubentry()
00158 {
00159    // Performs an LDAPSearch with the attribute "subschemaSubentry" to
00160    // be returned with the result. The value of this attribute is
00161    // extracted and returned as const char.
00162 
00163    TList *attrs = new TList;
00164    attrs->SetOwner();
00165    attrs->AddLast(new TObjString("subschemaSubentry"));
00166 
00167    TLDAPResult *result = Search("", LDAP_SCOPE_BASE, 0, attrs, 0);
00168 
00169    TLDAPEntry *entry = result->GetNext();
00170 
00171    TLDAPAttribute *attribute = entry->GetAttribute();
00172 
00173    const char *subschema = attribute->GetValue();
00174 
00175    delete entry;
00176    delete result;
00177    delete attrs;
00178 
00179    return subschema;
00180 }
00181 
00182 //______________________________________________________________________________
00183 TLDAPResult *TLDAPServer::GetObjectClasses()
00184 {
00185    // Calls GetSubschemaSubentry() and performs and LDAPSearch with
00186    // the attribute "objectClasses" to be returned with the result.
00187    // The returned result object must be deleted by the user.
00188 
00189    const char *subschema = GetSubschemaSubentry();
00190 
00191    TList *attrs = new TList;
00192    attrs->SetOwner();
00193    attrs->AddLast(new TObjString("objectClasses"));
00194 
00195    TLDAPResult *result = Search(subschema, LDAP_SCOPE_BASE, 0, attrs, 0);
00196 
00197    delete attrs;
00198 
00199    return result;
00200 }
00201 
00202 //______________________________________________________________________________
00203 TLDAPResult *TLDAPServer::GetAttributeTypes()
00204 {
00205    // Calls GetSubschemaSubentry() and performs and LDAPSearch with the
00206    // attribute "attributeTypes" to be returned with the result.
00207    // The returned result object must be deleted by the user.
00208 
00209    const char *subschema = GetSubschemaSubentry();
00210 
00211    TList *attrs = new TList;
00212    attrs->SetOwner();
00213    attrs->AddLast(new TObjString("attributeTypes"));
00214 
00215    TLDAPResult *result = Search(subschema, LDAP_SCOPE_BASE, 0, attrs, 0);
00216 
00217    delete attrs;
00218 
00219    return result;
00220 }
00221 
00222 //______________________________________________________________________________
00223 TLDAPResult *TLDAPServer::Search(const char *base, Int_t scope,
00224                                  const char *filter, TList *attrs,
00225                                  Bool_t attrsonly)
00226 {
00227    // Performs searching at the LDAP directory.
00228    // Return value:     a TLDAPResult object or 0 in case of error.
00229    //                   Result needs to be deleted by user.
00230    // const char *base: Specifies the base object for the search operation
00231    // Int_t scope:      Specifies the portion of the LDAP tree, relative to
00232    //                   the base object, to search.
00233    //                   Must be one of LDAP_SCOPE_BASE (==0),
00234    //                   LDAP_SCOPE_ONELEVEL (==1) or LDAP_SCOPE_SUBTREE (==2).
00235    // char *filter:     The criteria during the search to determine which
00236    //                   entries to return, 0 means that the filter
00237    //                   "(objectclass=*)" will be applied
00238    // TList *attrs:     The TList of attributes to be returned along with
00239    //                   each entry, 0 means that all available attributes
00240    //                   should be returned.
00241    // Int_t attrsonly:  This parameter is a boolean specifying whether both
00242    //                   types and values should be returned with each
00243    //                   attribute (zero) or types only should be returned
00244    //                   (non-zero).
00245 
00246    Bind();
00247 
00248    Int_t errcode;
00249    TLDAPResult *result = 0;
00250 
00251    if (IsConnected()) {
00252 
00253       LDAPMessage *searchresult;
00254       char **attrslist = 0;
00255       if (attrs) {
00256          Int_t n = attrs->GetSize();
00257          attrslist = new char* [n + 1];
00258          for (Int_t i = 0; i < n; i++)
00259             attrslist[i] = (char*) ((TObjString*)attrs->At(i))->GetName();
00260          attrslist[n] = 0;
00261       }
00262       if (filter == 0)
00263          filter = "(objectClass=*)";
00264 
00265       errcode = ldap_search_s(fLd, base, scope, filter, attrslist,
00266                               attrsonly, &searchresult);
00267 
00268       delete [] attrslist;
00269 
00270       if (errcode == LDAP_SUCCESS) {
00271          result = new TLDAPResult(fLd, searchresult);
00272       } else {
00273          ldap_msgfree(searchresult);
00274          Error("Search", "%s", ldap_err2string(errcode));
00275       }
00276 
00277    } else {
00278       errcode = LDAP_SERVER_DOWN;
00279       Error("Search", "%s", "server is not connected");
00280    }
00281 
00282    return result;
00283 }
00284 
00285 //______________________________________________________________________________
00286 Int_t TLDAPServer::AddEntry(TLDAPEntry &entry)
00287 {
00288    // Adds entry to the LDAP tree.
00289    // Be sure that you are bound with write permissions.
00290    // Return value: LDAP error code.
00291 
00292    Bind();
00293 
00294    Int_t errcode;
00295    if (IsConnected()) {
00296       LDAPMod **ms = entry.GetMods(0);
00297       errcode = ldap_add_s(fLd, entry.GetDn(), ms);
00298       TLDAPServer::DeleteMods(ms);
00299       if (errcode != LDAP_SUCCESS)
00300          Error("AddEntry", "%s", ldap_err2string(errcode));
00301    } else {
00302       errcode = LDAP_SERVER_DOWN;
00303       Error("AddEntry", "server is not connected");
00304    }
00305    return errcode;
00306 }
00307 
00308 //______________________________________________________________________________
00309 Int_t TLDAPServer::ModifyEntry(TLDAPEntry &entry, Int_t mode)
00310 {
00311    // Modifies specified entry.
00312    // Be sure that you are bound with write permissions.
00313    // Return value:      LDAP error code, 0 = success.
00314    // TLDAPEntry &entry: Entry to be modified.
00315    // Int_t mode:        Modifying mode.
00316    //                    Should be one of LDAP_MOD_ADD (==0),
00317    //                    LDAP_MOD_DELETE (==1) or LDAP_MOD_REPLACE (==2)
00318    //                    Specifies what to do with all the entry's attributes
00319    //                    and its values - add to the corresponding entry on
00320    //                    the server, delete from it, or replace the
00321    //                    corresponding attributes with new values
00322 
00323    Bind();
00324 
00325    Int_t errcode;
00326    if (IsConnected()) {
00327       LDAPMod **ms = entry.GetMods(mode);
00328       errcode = ldap_modify_s(fLd, entry.GetDn(), ms);
00329       TLDAPServer::DeleteMods(ms);
00330       if (errcode != LDAP_SUCCESS)
00331          Error("ModifyEntry", "%s", ldap_err2string(errcode));
00332    } else {
00333       errcode = LDAP_SERVER_DOWN;
00334       Error("ModifyEntry", "server is not connected");
00335    }
00336    return errcode;
00337 }
00338 
00339 //______________________________________________________________________________
00340 Int_t TLDAPServer::DeleteEntry(const char *dn)
00341 {
00342    // Deletes the entry with specified DN, the base entry must exist.
00343    // Be sure that you are bound with write permissions.
00344    // Return value: LDAP error code, 0 = succes.
00345 
00346    Bind();
00347 
00348    Int_t errcode;
00349    if (IsConnected()) {
00350       errcode = ldap_delete_s(fLd, dn);
00351       if (errcode != LDAP_SUCCESS)
00352          Error("DeleteEntry", "%s", ldap_err2string(errcode));
00353    } else {
00354       errcode = LDAP_SERVER_DOWN;
00355       Error("DeleteEntry", "server is not connected");
00356    }
00357    return errcode;
00358 }
00359 
00360 //______________________________________________________________________________
00361 Int_t TLDAPServer::RenameEntry(const char *dn, const char *newrdn, Bool_t removeattr)
00362 {
00363    // Renames the entry with specified DN, the entry must be leaf
00364    // Be sure that you are bound with the write permissions
00365    // Return value:      LDAP error code, 0 = succes
00366    // char *dn:          Distinguished name of entry to be renamed.
00367    //                    This entry must be a leaf in the LDAP directory tree.
00368    // char *newrdn:      The new relative distinguished name to give the entry
00369    //                    being renamed.
00370    // Bool_t removeattr: This parameter specifies whether or not the
00371    //                    attribute values in the old relative distinguished
00372    //                    name should be removed from the entry
00373    //                    or retained as non-distinguished attributes.
00374 
00375    Int_t errcode;
00376    if (IsConnected()) {
00377       errcode = ldap_modrdn2_s(fLd, dn, newrdn, removeattr);
00378       if (errcode != LDAP_SUCCESS)
00379          Error( "RenameEntry", "%s", ldap_err2string(errcode));
00380    } else {
00381       errcode = LDAP_SERVER_DOWN;
00382       Error("RenameEntry", "server is not connected");
00383    }
00384    return errcode;
00385 }
00386 
00387 //______________________________________________________________________________
00388 void TLDAPServer::DeleteMods(LDAPMod **mods)
00389 {
00390    // Deletes the array of LDAPMod structures and frees its memory.
00391    // LDAPMod **mods: Pointer to the zero-terminated array of pointers
00392    //                 to LDAPMod structures
00393 
00394 #if 1
00395    ldap_mods_free(mods, 1);
00396 #else
00397    Int_t i = 0;
00398    LDAPMod *mod;
00399    while ((mod = mods[i++]) != 0) {
00400       if (mod->mod_op & LDAP_MOD_BVALUES) {
00401          ber_bvecfree(mod->mod_bvalues);
00402       } else {
00403          Int_t j = 0;
00404          char *c;
00405          while ((c = mod->mod_values[j++]) != 0)
00406             delete c;
00407       }
00408       delete mod->mod_type;
00409       delete mod;
00410    }
00411    delete mods;
00412 #endif
00413 }

Generated on Tue Jul 5 14:45:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1