1N/A * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. 1N/A * The contents of this file are subject to the Netscape Public 1N/A * License Version 1.1 (the "License"); you may not use this file 1N/A * except in compliance with the License. You may obtain a copy of 1N/A * Software distributed under the License is distributed on an "AS 1N/A * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 1N/A * implied. See the License for the specific language governing 1N/A * rights and limitations under the License. 1N/A * The Original Code is Mozilla Communicator client code, released 1N/A * The Initial Developer of the Original Code is Netscape 1N/A * Communications Corporation. Portions created by Netscape are 1N/A * Copyright (C) 1998-1999 Netscape Communications Corporation. All 1N/A * Copyright (c) 1990 Regents of the University of Michigan. 1N/A * All rights reserved. 1N/Astatic char copyright[] =
"@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
1N/A * ldap_search - initiate an ldap search operation. Parameters: 1N/A * ld LDAP descriptor 1N/A * base DN of the base object 1N/A * scope the search scope - one of LDAP_SCOPE_BASE, 1N/A * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE 1N/A * filter a string containing the search filter 1N/A * (e.g., "(|(cn=bob)(sn=bob))") 1N/A * attrs list of attribute types to return for matches 1N/A * attrsonly 1 => attributes only 0 => attributes and values 1N/A * char *attrs[] = { "mail", "title", 0 }; 1N/A * msgid = ldap_search( ld, "c=us@o=UM", LDAP_SCOPE_SUBTREE, "cn~=bob", 1N/A * attrs, attrsonly ); 1N/A return( -
1 );
/* error is in ld handle */ 1N/A * LDAPv3 extended search. 1N/A * Returns an LDAP error code. 1N/A * It is an error to pass in a zero'd timeval. 1N/A * Like ldap_search_ext() except an integer timelimit is passed instead of 1N/A * using the overloaded struct timeval *timeoutp. 1N/A unsigned long key;
/* XXXmcs: memcache */ 1N/A * XXXmcs: should use cache function pointers to hook in memcache 1N/A /* check the cache */ 1N/A /* caching off or did not find it in the cache - check the net */ 1N/A /* send the message */ 1N/A * XXXmcs: should use cache function pointers to hook in memcache 1N/A * Convert a non-NULL timeoutp to a value in seconds that is appropriate to 1N/A * send in an LDAP search request. If timeoutp is NULL, return defaultvalue. 1N/A * both tv_sec and tv_usec are less than one (zero?) so 1N/A * to maintain compatiblity with our "zero means no limit" 1N/A * convention we pass no limit to the server. 1N/A/* returns an LDAP error code and also sets it in ld */ 1N/A * Create the search request. It looks like this: 1N/A * SearchRequest := [APPLICATION 3] SEQUENCE { 1N/A * baseObject DistinguishedName, 1N/A * scope ENUMERATED { 1N/A * derefAliases ENUMERATED { 1N/A * neverDerefaliases (0), 1N/A * derefInSearching (1), 1N/A * derefFindingBaseObj (2), 1N/A * alwaysDerefAliases (3) 1N/A * sizelimit INTEGER (0 .. 65535), 1N/A * timelimit INTEGER (0 .. 65535), 1N/A * attrsOnly BOOLEAN, 1N/A * attributes SEQUENCE OF AttributeType 1N/A * wrapped in an ldap message. 1N/A /* create a message to send */ 1N/A else if ( *s ==
')' )
1N/A * We have (x(filter)...) with str sitting on 1N/A * the x. We have to find the paren matching 1N/A * the one before the x and put the intervening 1N/A * filters by calling put_filter_list(). 1N/A /* put explicit tag */ 1N/A /* flush explicit tagged thang */ 1N/A * A Filter looks like this: 1N/A * Filter ::= CHOICE { 1N/A * and [0] SET OF Filter, 1N/A * or [1] SET OF Filter, 1N/A * equalityMatch [3] AttributeValueAssertion, 1N/A * substrings [4] SubstringFilter, 1N/A * greaterOrEqual [5] AttributeValueAssertion, 1N/A * lessOrEqual [6] AttributeValueAssertion, 1N/A * present [7] AttributeType,, 1N/A * approxMatch [8] AttributeValueAssertion 1N/A * SubstringFilter ::= SEQUENCE { 1N/A * type AttributeType, 1N/A * SEQUENCE OF CHOICE { 1N/A * initial [0] IA5String, 1N/A * any [1] IA5String, 1N/A * final [2] IA5String 1N/A * Note: tags in a choice are always explicit 1N/A "put_filter: simple\n", 0, 0, 0 );
1N/A default:
/* assume it's a simple type=value filter */ 1N/A * Put a list of filters like this "(filter1)(filter2)..." 1N/A /* now we have "(filter)" with str pointing to it */ 1N/A * is_valid_attr - returns 1 if a is a syntactically valid left-hand side 1N/A * of a filter expression, 0 otherwise. A valid string may contain only 1N/A * letters, numbers, hyphens, semicolons, colons and periods. examples: 1N/A * 1.2.3.4;binary;dynamic 1N/A * For compatibility with older servers, we also allow underscores in 1N/A * attribute types, even through they are not allowed by the LDAPv3 RFCs. 1N/A char *
oid;
/* for v3 extended filter */ 1N/A rc = -
1;
/* pessimistic */ 1N/A case ':':
/* extended filter - v3 only */ 1N/A * extended filter looks like this: 1N/A * [type][':dn'][':'oid]':='value 1N/A * where one of type or :oid is required. 1N/A * Undo in place both LDAPv2 (RFC-1960) and LDAPv3 (hexadecimal) escape 1N/A * sequences within the null-terminated string 'val'. The resulting value 1N/A * may contain null characters. 1N/A * If 'val' contains invalid escape sequences we return -1. 1N/A * Otherwise the length of the unescaped value is returned. 1N/A for ( s = d =
val; *s; s++ ) {
1N/A * first try LDAPv3 escape (hexadecimal) sequence 1N/A * LDAPv2 (RFC1960) escape sequence 1N/A }
else if ( *s !=
'\\' ) {
1N/A * convert character 'c' that represents a hexadecimal digit to an integer. 1N/A * if 'c' is not a hexidecimal digit [0-9A-Fa-f], -1 is returned. 1N/A * otherwise the converted value is returned. 1N/A if ( c >=
'0' && c <=
'9' ) {
1N/A if ( c >=
'A' && c <=
'F' ) {
1N/A return( c -
'A' +
10 );
1N/A if ( c >=
'a' && c <=
'f' ) {
1N/A return( c -
'a' +
10 );
1N/A * It is an error to pass in a zero'd timeval. 1N/A * Error. ldap_result() sets *res to NULL for us.