pike.git / lib / modules / Protocols.pmod / LDAP.pmod / client.pike

version» Context lines:

pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:1:   #pike __REAL_VERSION__      // LDAP client protocol implementation for Pike.   // - // $Id: client.pike,v 1.71 2005/03/08 16:41:32 mast Exp $ + // $Id: client.pike,v 1.72 2005/03/09 12:28:26 mast Exp $   //   // Honza Petrous, hop@unibase.cz   //   // ----------------------------------------------------------------------   //   // History:   //   // v0.0 1998-05-25 Starting up!   // v1.0 1998-06-21 Core functions (open, bind, unbind, delete, add,   // compare, search), only V2 operations,
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:80:   #endif      // ------------------------      // ASN.1 decode macros   #define ASN1_DECODE_RESULTAPP(X) (.ldap_privates.ldap_der_decode(X)->elements[1]->get_tag())   #define ASN1_DECODE_RESULTCODE(X) (int)(.ldap_privates.ldap_der_decode(X)->elements[1]->elements[0]->value->cast_to_int())   #define ASN1_DECODE_RESULTSTRING(X) (.ldap_privates.ldap_der_decode(X)->elements[1]->elements[2]->value)   #define ASN1_DECODE_RESULTREFS(X) (.ldap_privates.ldap_der_decode(X)->elements[1]->elements[3]->elements)   #define ASN1_DECODE_ENTRIES(X) _New_decode(X) - #define ASN1_DECODE_DN(X) (string)((X)->elements[0]->value) + #define ASN1_DECODE_DN(X) ((string)((X)->elements[0]->value))   #define ASN1_DECODE_RAWDEBUG(X) (.ldap_privates.ldap_der_decode(X)->debug_string()) - #define ASN1_GET_ATTR_ARRAY(X) (array)((X)->elements[1]->elements) + #define ASN1_GET_ATTR_ARRAY(X) (sizeof ((X)->elements) > 1 && \ +  (array) ((X)->elements[1]->elements))   #define ASN1_GET_ATTR_NAME(X) ((X)->elements[0]->value)       //! Contains the client implementation of the LDAP protocol.    //! All of the version 2 protocol features are implemented    //! but only the base parts of the version 3.       inherit .protocol;       private {    int binded = 0; // flag for v2 operations
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:112:    //! Contains the result of a LDAP search.    //!    //! @seealso    //! @[LDAP.client.search], @[LDAP.client.result.fetch]    //!    class result // ------------------    {       private int resultcode = LDAP_SUCCESS;    private string resultstring; -  private int entrycnt = 0; +     private int actnum = 0;    private array(mapping(string:array(string))) entry = ({});    array(string) referrals;       private string utf2s(string in) {    // catched variant of utf8_to_string needed for tagged octet string data       string out = "";    catch( out = utf8_to_string(in) );    return out;
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:144:    if(ver == 3) {    // deUTF8    res = Array.map(res, utf2s);    }    return res;    }       private array _New_decode(array ar) {       array res = ({}); -  array entry1; -  mapping attrs; -  object oder; +        foreach(ar, string raw1) { -  oder = (.ldap_privates.ldap_der_decode(raw1)->elements[1]); -  attrs = (["dn":({ASN1_DECODE_DN(oder)})]); -  if(catch(entry1 = ASN1_GET_ATTR_ARRAY(oder))) continue; +  object oder = (.ldap_privates.ldap_der_decode(raw1)->elements[1]); +  mapping(string:array) attrs = (["dn":({ASN1_DECODE_DN(oder)})]); +  if(array entry1 = ASN1_GET_ATTR_ARRAY(oder)) {    foreach(entry1, object attr1) { -  attrs += ([ASN1_GET_ATTR_NAME(attr1):_get_attr_values(ldap_version, attr1)]); +  attrs[ASN1_GET_ATTR_NAME(attr1)] = _get_attr_values(ldap_version, attr1);    }    res += ({attrs});    } -  +  }       return res;    } // _New_decode       //!    //! You can't create instances of this object yourself.    //! The only way to create it is via a search of a LDAP server.    object|int create(array rawres, int|void stuff) {    // rawres: array of result in raw format, but WITHOUT LDAP PDU !!!    // stuff: 1=bind result; ...
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:192: Inside #if defined(V3_REFERRALS)
  #ifdef V3_REFERRALS    // referral (v3 mode)    if(resultcode == 10) {    referrals = ({});    foreach(ASN1_DECODE_RESULTREFS(rawres[lastel]), object ref1)    referrals += ({ ref1->value });    DWRITE(sprintf("result.create: refs=%O\n",referrals));    }   #endif    DWRITE(sprintf("result.create: elements=%d\n",lastel+1)); + #if 0 +  DWRITE(sprintf("result.create: entries=%O\n",rawres[..lastel-1])); + #endif    if (lastel) { // Have we any entry?    entry = ASN1_DECODE_ENTRIES(rawres[..lastel-1]); -  entrycnt = sizeof(entry); //num_entries(); +     }      #if 0    // Context specific proccessing of 'rawres'    switch(stuff) {    case 1: DWRITE("result.create: stuff=1\n");    break;    default: DWRITE(sprintf("result.create: stuff=%d\n", stuff));       }
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:233:    string error_string() {    return ((stringp(resultstring) && sizeof(resultstring)) ?    resultstring : ldap_errlist[resultcode]);    }       //!    //! Returns the number of entries.    //!    //! @seealso    //! @[LDAP.client.result.count_entries] -  int num_entries() { return entrycnt; } +  int num_entries() { return sizeof (entry); }       //!    //! Returns the number of entries from current cursor    //! possition till end of the list.    //!    //! @seealso    //! @[LDAP.client.result.first], @[LDAP.client.result.next] -  int count_entries() { return entrycnt - actnum; } +  int count_entries() { return sizeof (entry) - actnum; }    -  //! Returns a mapping with an entry for each attribute. -  //! Each entry is an array of values of the attribute. +  //! Returns the current entry pointed to by the cursor. +  //! a mapping with an entry for each attribute. Each value +  //! is an array of the values for the attribute. The    //!    //! @param index    //! Optional argument can be used for direct access    //! to the entry other then currently pointed by cursor. -  +  //! +  //! @returns +  //! The return value is a mapping describing the entry: +  //! +  //! @mapping +  //! @member string attribute +  //! An attribute in the entry. The value is an array containing +  //! the returned attribute value(s) on string form. It may be +  //! an empty array if only the attribute types were requested +  //! or if all values were excluded. +  //! +  //! @member string "dn" +  //! This special entry contains the object name of the entry as +  //! a distinguished name. +  //! @endmapping +  //! +  //! Zero is returned if the cursor is outside the valid range of +  //! entries. +  //! +  //! @note +  //! Don't be destructive on the returned mapping. +  //! +  //! @seealso +  //! @[fetch_all]    int|mapping(string:array(string)) fetch(int|void idx) {       if (!idx)    idx = actnum + 1;    if ((idx <= num_entries()) && (idx > 0)) {    actnum = idx - 1;    return entry[actnum];    }    return 0;    }
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:289:    //! @seealso    //! @[LDAP.client.result.next]    int next() {    if (actnum < (num_entries()-1)) {    actnum++;    return count_entries();    }    return 0;    }    +  array(mapping(string:array(string))) fetch_all() +  //! Convenience function to fetch all entries at once. The cursor +  //! isn't affected. +  //! +  //! @returns +  //! Returns an array where each element is the entry from the +  //! result. Don't be destructive on the returned value. +  //! +  //! @seealso +  //! @[fetch] +  { +  return entry; +  } +     } // end of class 'result' ---------------       // helper functions and macros      #ifdef ENABLE_PAGED_SEARCH   #define IF_ELSE_PAGED_SEARCH(X,Y) X   #else /* !ENABLE_PAGED_SEARCH */   #define IF_ELSE_PAGED_SEARCH(X,Y) Y   #endif   
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:352:    //! @decl void create(string url)    //! @decl void create(string url, object context)    //!    //! Create object. The first optional argument can be used later    //! for subsequence operations. The second one can specify    //! TLS context of connection. The default context only allows    //! 128-bit encryption methods, so you may need to provide your    //! own context if your LDAP server supports only export encryption.    //!    //! @param url -  //! LDAP server URL in form -  //! @expr{"ldap://hostname/basedn?attrlist?scope?ext"@} +  //! LDAP server URL on the form +  //! @expr{"ldap://hostname/basedn?attrlist?scope?ext"@}. See RFC +  //! 2255.    //!    //! @param context    //! TLS context of connection    //!    //! @seealso    //! @[LDAP.client.bind], @[LDAP.client.search]    void create(string|void url, object|void context)    {    -  info = ([ "code_revision" : ("$Revision: 1.71 $"/" ")[1] ]); +  info = ([ "code_revision" : ("$Revision: 1.72 $"/" ")[1] ]);       if(!url || !sizeof(url))    url = LDAP_DEFAULT_URL;       lauth = parse_url(url);       if(!stringp(lauth->scheme) ||    ((lauth->scheme != "ldap")   #if constant(SSL.Cipher.CipherAlgorithm)    && (lauth->scheme != "ldaps")
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:425:   #else    if(lauth->scheme == "ldaps") {    THROW(({"LDAP: LDAPS is not available without SSL support.\n",backtrace()}));    }    else    ::create(low_fd);   #endif       DWRITE("client.create: connected!\n");    -  DWRITE(sprintf("client.create: remote = %s\n", query_address())); +  DWRITE(sprintf("client.create: remote = %s\n", low_fd->query_address()));    DWRITE_HI("client.OPEN: " + lauth->host + ":" + (string)(lauth->port) + " - OK\n");       binded = 0;       if(lauth->scope)    set_scope(lauth->scope);    if(lauth->basedn)    set_basedn(lauth->basedn);       } // create
pike.git/lib/modules/Protocols.pmod/LDAP.pmod/client.pike:1111:    //!    //! @param filter    //! Search filter used when searching directory objects. See RFC    //! 2254.    //!    //! @param attrs    //! The array of attribute names which will be returned by server.    //! for every entry.    //!    //! @param attrsonly -  //! The flag causes server return only attribute name but not -  //! the attribute values. +  //! The flag causes server return only attribute type (aka name) +  //! but not the attribute values.    //!    //! @param controls    //! Extra controls to send in the search query, to modify how the    //! server executes the search in various ways. The value is a    //! mapping with an entry for each control.    //! -  //! The mapping index is the object identifier in string form for -  //! the control type. The mapping value is an array where the -  //! first field is an integer flag and the second is the value of -  //! the control in string form. +  //! @mapping +  //! @member string object_identifier +  //! The index is the object identifier in string form for the +  //! control type. There are constants in @[Protocols.LDAP] for +  //! the object identifiers for some known controls.    //! -  //! The integer flag specifies whether the control is critical or -  //! not. If it is nonzero, the server returns an error if it -  //! doesn't understand the control. If it is zero, the server -  //! ignores it instead. +  //! The mapping value is an array of two elements:    //! -  //! The value may also be zero if the control doesn't need any -  //! value at all. +  //! @array +  //! @elem int 0 +  //! The first element is an integer flag that specifies +  //! whether the control is critical or not. If it is nonzero, +  //! the server returns an error if it doesn't understand the +  //! control. If it is zero, the server ignores it instead.    //! -  //! There are constants in @[Protocols.LDAP] for the object -  //! identifiers for some known controls. +  //! @elem string|int(0..0) 1 +  //! The second element is the string value to pass with the +  //! control. It may also be zero to not pass any value at all. +  //! @endarray +  //! @endmapping    //!    //! @returns    //! Returns object @[LDAP.client.result] on success, @expr{0@}    //! otherwise.    //!    //! @note -  //! For syntax of search filter see at RFC 1960 -  //! (http://community.roxen.com/developers/idocs/rfc/rfc1960.html). -  //! -  //! @note +     //! The API change: the returning code was changed in Pike 7.3+    //! to follow his logic better.    //!    //! @seealso    //! @[result], @[result.fetch], @[get_supported_controls],    //! @[Protocols.LDAP.quote_filter_value]    object|int search (string|void filter, array(string)|void attrs,    int|void attrsonly,    void|mapping(string:array(int|string)) controls) {