diff --git a/lib/modules/Protocols.pmod/LDAP.pmod/client.pike b/lib/modules/Protocols.pmod/LDAP.pmod/client.pike index 95e9910d809840e9904c530e8aa54b62f5f3feb4..842c2d4cc7412fb48fc372218059af107bd390f4 100644 --- a/lib/modules/Protocols.pmod/LDAP.pmod/client.pike +++ b/lib/modules/Protocols.pmod/LDAP.pmod/client.pike @@ -1,6 +1,6 @@ // LDAP client protocol implementation for Pike. // -// $Id: client.pike,v 1.15 2000/07/14 15:29:39 hop Exp $ +// $Id: client.pike,v 1.16 2000/07/20 14:54:41 hop Exp $ // // Honza Petrous, hop@unibase.cz // @@ -50,6 +50,9 @@ // // newer versions - see CVS at roxen.com (hop) // +// - corrected deUTF8 values in result +// - +// // Specifications: // // RFC 1558 (search filter representations) @@ -89,6 +92,7 @@ private int ldap_deref = 0; // 0: ... private int ldap_sizelimit = 0; private int ldap_timelimit = 0; + private mapping lauth = ([]); @@ -110,7 +114,7 @@ int count_entries() { return(entrycnt - actnum); } - private array _get_attr_values(object x) { + private array _get_attr_values(int ver, object x) { array res = ({}); @@ -118,6 +122,10 @@ return(res); foreach(x->elements[1]->elements, object val1) res += ({ val1->value }); + if(ver == 3) { + // deUTF8 + res = Array.map(res, utf8_to_string); + } return(res); } @@ -131,16 +139,11 @@ attrs = (["dn":({ASN1_DECODE_DN(raw1)})]); entry1 = ASN1_GET_ATTR_ARRAY(raw1); foreach(entry1, object attr1) { - attrs += ([ASN1_GET_ATTR_NAME(attr1):_get_attr_values(attr1)]); + attrs += ([ASN1_GET_ATTR_NAME(attr1):_get_attr_values(ldap_version, attr1)]); } res += ({attrs}); } - if(ldap_version == 3) { - // deUTF8 - res = Array.map(res, utf8_to_string); - } - return (res); } // _New_decode @@ -232,6 +235,8 @@ THROW(({"LDAP: Must binded first.\n",backtrace()})); return(-ldap_errno); } + if ((ldap_version == 3) && !binded) + bind(); return(0); } @@ -249,30 +254,33 @@ // // create(string|void server) // - // server: server name (hostname or IP, default: 127.0.0.1) - // with optional port number (default: 389) + // server: server URL in form "ldap://hostname/basedn???!bindname= void create(string|void server) { - int port = LDAP_DEFAULT_PORT; if(!server || !sizeof(server)) server = (string)LDAP_DEFAULT_HOST; - else - if(predef::search(server,":")>0) { - port = (int)((server / ":")[1]); - server = (server / ":")[0]; - } + + lauth = parse_url(server); + + if(!stringp(lauth->scheme) || (lauth->scheme != "ldap")) { + THROW(({"Unknown scheme in server URL.\n",backtrace()})); + } - ::create(server, port); - if(!::connected) - { + ::create(lauth->host||LDAP_DEFAULT_HOST, lauth->port||LDAP_DEFAULT_PORT); + if(!::connected) { THROW(({"Failed to connect to LDAP server.\n",backtrace()})); } DWRITE(sprintf("client.create: remote = %s\n", query_address())); - DWRITE_HI("client.OPEN: " + server + " - OK\n"); + DWRITE_HI("client.OPEN: " + lauth->host||LDAP_DEFAULT_HOST + (string)(lauth->port||LDAP_DEFAULT_PORT) + " - OK\n"); binded = 0; + if(lauth->scope) + set_scope(lauth->scope); + if(lauth->basedn) + set_basedn(lauth->basedn); + } // create private mixed send_bind_op(string name, string password) { @@ -308,7 +316,7 @@ if (chk_ver()) return(-ldap_errno); if (!stringp(name)) - name = ""; + name = mappingp(lauth->ext) ? lauth->ext->bindname||"" : ""; if (!stringp(password)) password = ""; ldap_version = proto; @@ -977,15 +985,27 @@ ar = url / "?"; switch (sizeof(ar)) { - case 5: res += ([ "ext" : ar[4] ]); + case 5: if (sizeof(ar[4])) { + mapping extensions = ([]); + foreach(ar[4] / ",", string ext) { + int ix = predef::search(ext, "="); + if(ix) + extensions += ([ ext[..(ix-1)] : replace(ext[ix+1..],QUOTED_COMMA, ",") ]); + } + if (sizeof(extensions)) + res += ([ "ext" : extensions ]); + } + //case 5: res += ([ "ext" : ar[4] ]); case 4: res += ([ "filter" : ar[3] ]); - case 3: res += ([ "scope" : ar[2] ]); + case 3: switch (ar[2]) { + case "sub": res += ([ "scope" : 2 ]); break; + case "one": res += ([ "scope" : 1 ]); break; + default: res += ([ "scope" : 0]); // = "base" + } case 2: res += sizeof(ar[1]) ? ([ "attributes" : ar[1] / "," ]) : ([]); - case 1: res += ([ "dn" : ar[0] ]); + case 1: res += ([ "basedn" : ar[0] ]); } - //write("DEB: mapping: [%O] \n", res); - return (res); } //parse_uri diff --git a/lib/modules/Protocols.pmod/LDAP.pmod/ldap_globals.h b/lib/modules/Protocols.pmod/LDAP.pmod/ldap_globals.h index dc92de3e71974763fae3bc1423c21ba6b5bcbf81..4486189620f454bdf9d720052a4cb85391d26cbb 100644 --- a/lib/modules/Protocols.pmod/LDAP.pmod/ldap_globals.h +++ b/lib/modules/Protocols.pmod/LDAP.pmod/ldap_globals.h @@ -19,8 +19,10 @@ #define LDAP_DEFAULT_PORT 389 -#define LDAP_DEFAULT_HOST "127.0.0.1" -#define LDAP_DEFAULT_VERSION 2 +#define LDAP_DEFAULT_HOST "ldap://127.0.0.1/" +#define LDAP_DEFAULT_VERSION 3 + +#define QUOTED_COMMA "%2c" // --- Debug low level operations --- #define DWRITE(X)