mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-18 18:18:06 -05:00
Pull in a variety of bug fixes from HEAD including
critical client control handling tls cert checking sasl/tls ref handling empty dn handling Also removed ufn search (normally I would have left it in but the merge was easier this way).
This commit is contained in:
parent
7c0ec6b3eb
commit
ff8f7545e5
40 changed files with 353 additions and 1118 deletions
|
|
@ -7,12 +7,11 @@ Public License. A copy of this license is available at
|
|||
http://www.OpenLDAP.org/license.html or in file LICENSE in the
|
||||
top-level directory of the distribution.
|
||||
|
||||
Individual files and/or contributed packages may be copyright by
|
||||
other parties and use subject to additional restrictions.
|
||||
Individual files and/or contributed packages may contain material
|
||||
copyright by other parties and use subject to additional restrictions.
|
||||
|
||||
This work is derived from the University of Michigan LDAP v3.3
|
||||
distribution. Information concerning this software is available
|
||||
at: http://www.umich.edu/~dirsvcs/ldap/
|
||||
software <http://www.umich.edu/~dirsvcs/ldap/>.
|
||||
|
||||
This work also contains materials derived from public sources.
|
||||
|
||||
|
|
|
|||
|
|
@ -129,18 +129,6 @@ main( int argc, char **argv )
|
|||
}
|
||||
|
||||
result = NULL;
|
||||
if ( strchr( key, ',' ) != NULL ) {
|
||||
int ld_deref = LDAP_DEREF_FINDING;
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &ld_deref);
|
||||
if ( (rc = ldap_ufn_search_s( ld, key, attrs, 0, &result ))
|
||||
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED &&
|
||||
rc != LDAP_TIMELIMIT_EXCEEDED )
|
||||
{
|
||||
ldap_perror( ld, "ldap_ufn_search_s" );
|
||||
exit( -1 );
|
||||
}
|
||||
matches = ldap_count_entries( ld, result );
|
||||
} else {
|
||||
for ( fi = ldap_getfirstfilter( filtd, "rp500", key );
|
||||
fi != NULL; fi = ldap_getnextfilter( filtd ) ) {
|
||||
if ( (rc = ldap_search_s( ld, base, LDAP_SCOPE_SUBTREE,
|
||||
|
|
@ -157,7 +145,6 @@ main( int argc, char **argv )
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( matches == 1 ) {
|
||||
e = ldap_first_entry( ld, result );
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ do_search( LDAP *ld, char *buf )
|
|||
{
|
||||
char *dn, *rdn;
|
||||
char **title;
|
||||
int rc = 0, matches = 0, i, ufn;
|
||||
int rc = 0, matches = 0, i;
|
||||
struct timeval tv;
|
||||
LDAPFiltDesc *fd;
|
||||
LDAPFiltInfo *fi = NULL;
|
||||
|
|
@ -270,25 +270,6 @@ do_search( LDAP *ld, char *buf )
|
|||
#endif
|
||||
0 };
|
||||
|
||||
ufn = 0;
|
||||
#ifdef FINGER_UFN
|
||||
if ( strchr( buf, ',' ) != NULL ) {
|
||||
ldap_ufn_setprefix( ld, base );
|
||||
tv.tv_sec = FINGER_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
ldap_ufn_timeout( (void *) &tv );
|
||||
|
||||
if ( (rc = ldap_ufn_search_s( ld, buf, attrs, 0, &result ))
|
||||
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED ) {
|
||||
fprintf( stderr, FINGER_UNAVAILABLE );
|
||||
ldap_perror( ld, "ldap_search_st" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
matches = ldap_count_entries( ld, result );
|
||||
ufn = 1;
|
||||
} else {
|
||||
#endif
|
||||
if ( (fd = ldap_init_getfilter( filterfile ))
|
||||
== NULL ) {
|
||||
fprintf( stderr, "Cannot open filter file (%s)\n",
|
||||
|
|
@ -318,9 +299,6 @@ do_search( LDAP *ld, char *buf )
|
|||
ldap_msgfree( result );
|
||||
result = NULL;
|
||||
}
|
||||
#ifdef FINGER_UFN
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( rc == LDAP_SIZELIMIT_EXCEEDED ) {
|
||||
printf( "(Partial results - a size limit was exceeded)\r\n" );
|
||||
|
|
@ -336,7 +314,7 @@ do_search( LDAP *ld, char *buf )
|
|||
exit( EXIT_FAILURE );
|
||||
} else if ( matches <= FINGER_LISTLIMIT ) {
|
||||
printf( "%d %s match%s found for \"%s\":\r\n", matches,
|
||||
ufn ? "UFN" : fi->lfi_desc, matches > 1 ? "es" : "", buf );
|
||||
fi->lfi_desc, matches > 1 ? "es" : "", buf );
|
||||
fflush( stdout );
|
||||
|
||||
for ( e = ldap_first_entry( ld, result ); e != NULL; ) {
|
||||
|
|
@ -348,7 +326,7 @@ do_search( LDAP *ld, char *buf )
|
|||
}
|
||||
} else {
|
||||
printf( "%d %s matches for \"%s\":\r\n", matches,
|
||||
ufn ? "UFN" : fi->lfi_desc, buf );
|
||||
fi->lfi_desc, buf );
|
||||
fflush( stdout );
|
||||
|
||||
#ifdef FINGER_SORT_ATTR
|
||||
|
|
|
|||
|
|
@ -482,24 +482,6 @@ do_search( LDAP *ld, FILE *fp, char *buf )
|
|||
LDAPMessage *e, *res;
|
||||
static char *attrs[] = { "title", 0 };
|
||||
|
||||
#ifdef GO500_UFN
|
||||
if ( strchr( buf, ',' ) != NULL ) {
|
||||
ldap_ufn_setprefix( ld, base );
|
||||
tv.tv_sec = GO500_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
ldap_ufn_timeout( (void *) &tv );
|
||||
|
||||
if ( (rc = ldap_ufn_search_s( ld, buf, attrs, 0, &res ))
|
||||
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED ) {
|
||||
fprintf(fp,
|
||||
"0An error occurred (explanation)\t@%d\t%s\t%d\r\n",
|
||||
rc, myhost, myport );
|
||||
return;
|
||||
}
|
||||
|
||||
matches = ldap_count_entries( ld, res );
|
||||
} else {
|
||||
#endif
|
||||
if ( (filtd = ldap_init_getfilter( filterfile )) == NULL ) {
|
||||
fprintf( stderr, "Cannot open filter file (%s)\n",
|
||||
filterfile );
|
||||
|
|
@ -525,9 +507,6 @@ do_search( LDAP *ld, FILE *fp, char *buf )
|
|||
break;
|
||||
}
|
||||
ldap_getfilter_free( filtd );
|
||||
#ifdef GO500_UFN
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( matches <= 0 ) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -743,27 +743,6 @@ do_search( LDAP *ld, FILE *fp, char *query )
|
|||
*filter++ = '\0';
|
||||
base = query;
|
||||
|
||||
#ifdef GO500GW_UFN
|
||||
if ( strchr( filter, ',' ) != NULL ) {
|
||||
ldap_ufn_setprefix( ld, base );
|
||||
timeout.tv_sec = GO500GW_TIMEOUT;
|
||||
timeout.tv_usec = 0;
|
||||
ldap_ufn_timeout( (void *) &timeout );
|
||||
|
||||
deref = LDAP_DEREF_FINDING;
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
|
||||
|
||||
if ( (rc = ldap_ufn_search_s( ld, filter, attrs, 0, &res ))
|
||||
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED ) {
|
||||
fprintf(fp,
|
||||
"0An error occurred (explanation)\t@%d\t%s\t%d\r\n",
|
||||
rc, myhost, myport );
|
||||
return;
|
||||
}
|
||||
|
||||
count = ldap_count_entries( ld, res );
|
||||
} else {
|
||||
#endif
|
||||
if ( (scope = make_scope( ld, base )) == -1 ) {
|
||||
fprintf( fp, "3Bad scope\r\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
|
|
@ -801,9 +780,6 @@ do_search( LDAP *ld, FILE *fp, char *query )
|
|||
deref = LDAP_DEREF_ALWAYS;
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
|
||||
ldap_getfilter_free( filtd );
|
||||
#ifdef GO500GW_UFN
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( count == 0 ) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ query_cmd( struct msginfo *msgp, char *reply )
|
|||
LDAP *ldp;
|
||||
LDAPMessage *ldmsgp, *entry;
|
||||
char *dn;
|
||||
int matches, rc, ld_errno, ufn;
|
||||
int matches, rc, ld_errno;
|
||||
LDAPFiltDesc *lfdp;
|
||||
LDAPFiltInfo *lfi;
|
||||
struct ldap_disptmpl *tmpllist = NULL;
|
||||
|
|
@ -51,8 +51,6 @@ query_cmd( struct msginfo *msgp, char *reply )
|
|||
#endif
|
||||
NULL };
|
||||
|
||||
ufn = 0;
|
||||
|
||||
if ( msgp->msg_arg == NULL ) {
|
||||
return( help_cmd( msgp, reply ));
|
||||
}
|
||||
|
|
@ -95,23 +93,6 @@ query_cmd( struct msginfo *msgp, char *reply )
|
|||
|
||||
matches = 0;
|
||||
|
||||
#ifdef RCPT500_UFN
|
||||
if ( strchr( msgp->msg_arg, ',' ) != NULL ) {
|
||||
struct timeval tv;
|
||||
|
||||
ldap_ufn_setprefix( ldp, searchbase );
|
||||
if (( rc = ldap_ufn_search_s( ldp, msgp->msg_arg, attrs, 0, &ldmsgp ))
|
||||
!= LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED
|
||||
&& rc != LDAP_TIMELIMIT_EXCEEDED ) {
|
||||
report_ldap_err( ldp, reply );
|
||||
close_ldap( ldp );
|
||||
ldap_getfilter_free( lfdp );
|
||||
return( 0 );
|
||||
}
|
||||
matches = ldap_count_entries( ldp, ldmsgp );
|
||||
ufn = 1;
|
||||
} else {
|
||||
#endif /* RCPT500_UFN */
|
||||
|
||||
for ( lfi = ldap_getfirstfilter( lfdp, "rcpt500", msgp->msg_arg );
|
||||
lfi != NULL; lfi = ldap_getnextfilter( lfdp )) {
|
||||
|
|
@ -134,9 +115,6 @@ query_cmd( struct msginfo *msgp, char *reply )
|
|||
ldap_msgfree( ldmsgp );
|
||||
}
|
||||
}
|
||||
#ifdef RCPT500_UFN
|
||||
}
|
||||
#endif /* RCPT500_UFN */
|
||||
|
||||
if ( matches == 0 ) {
|
||||
sprintf( buf, "No matches were found for '%s'\n", msgp->msg_arg );
|
||||
|
|
@ -156,7 +134,7 @@ query_cmd( struct msginfo *msgp, char *reply )
|
|||
|
||||
if ( matches <= RCPT500_LISTLIMIT ) {
|
||||
sprintf( buf, "%d %s match%s found for '%s':\n\n", matches,
|
||||
ufn ? "UFN" : lfi->lfi_desc,
|
||||
lfi->lfi_desc,
|
||||
( matches > 1 ) ? "es" : "", msgp->msg_arg );
|
||||
strcat( reply, buf );
|
||||
|
||||
|
|
@ -184,7 +162,7 @@ query_cmd( struct msginfo *msgp, char *reply )
|
|||
|
||||
} else {
|
||||
sprintf( buf, "%d %s matches were found for '%s':\n",
|
||||
matches, ufn ? "UFN" : lfi->lfi_desc, msgp->msg_arg );
|
||||
matches, lfi->lfi_desc, msgp->msg_arg );
|
||||
strcat( reply, buf );
|
||||
append_entry_list( reply, msgp->msg_arg, ldp, ldmsgp );
|
||||
ldap_msgfree( ldmsgp );
|
||||
|
|
|
|||
|
|
@ -199,48 +199,6 @@ find( char *who, int quiet )
|
|||
search_attrs[k] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user-supplied name has any commas in it, we
|
||||
* assume that it is a UFN, and do everything right
|
||||
* here. If we don't find it, treat it as NOT a UFN.
|
||||
*/
|
||||
if (strchr(who, ',') != NULL) {
|
||||
int savederef, deref;
|
||||
#ifdef DEBUG
|
||||
if (debug & D_FIND)
|
||||
printf("\"%s\" appears to be a UFN\n", who);
|
||||
#endif
|
||||
ldap_get_option(ld, LDAP_OPT_DEREF, &savederef);
|
||||
deref = LDAP_DEREF_FINDING;
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
|
||||
|
||||
if ((rc = ldap_ufn_search_s(ld, who, search_attrs, FALSE, &res)) !=
|
||||
LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED &&
|
||||
rc != LDAP_TIMELIMIT_EXCEEDED) {
|
||||
ldap_perror(ld, "ldap_ufn_search_s");
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &savederef);
|
||||
return(NULL);
|
||||
}
|
||||
if ((matches = ldap_count_entries(ld, res)) < 0) {
|
||||
ldap_perror(ld, "ldap_count_entries");
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &savederef);
|
||||
return(NULL);
|
||||
} else if (matches == 1) {
|
||||
dn = ldap_get_dn(ld, ldap_first_entry(ld, res));
|
||||
rc = ldap_search_s(ld, dn, LDAP_SCOPE_BASE, NULL, read_attrs, FALSE, &res);
|
||||
ldap_memfree(dn);
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
ldap_perror(ld, "ldap_search_s");
|
||||
return(NULL);
|
||||
}
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &savederef);
|
||||
return(res);
|
||||
} else if (matches > 1 ) {
|
||||
return disambiguate( res, matches, read_attrs, who );
|
||||
}
|
||||
ldap_set_option(ld, LDAP_OPT_DEREF, &savederef);
|
||||
}
|
||||
|
||||
/*
|
||||
* Old users of the MTS *USERDIRECTORY will likely wrap the name
|
||||
* in quotes. Not only is this unnecessary, but it also won't work.
|
||||
|
|
@ -255,9 +213,6 @@ find( char *who, int quiet )
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* It wasn't a UFN, so look it up in the usual method.
|
||||
*/
|
||||
for (fi = ldap_getfirstfilter(lfdp, "ud", who); fi != NULL;
|
||||
fi = ldap_getnextfilter(lfdp)) {
|
||||
#ifdef DEBUG
|
||||
|
|
|
|||
|
|
@ -1,159 +0,0 @@
|
|||
|
||||
Individual Submission to LDAPExt Working Group R. Harrison
|
||||
Internet Draft Novell, Inc.
|
||||
Document: draft-rharrison-ldap-extpartresp-01.txt June, 2000
|
||||
Category: Proposed Standard
|
||||
|
||||
|
||||
Extended Partial Response
|
||||
Protocol Enhancement to LDAP v3
|
||||
|
||||
|
||||
Status of this Memo
|
||||
|
||||
This document is an Internet-Draft and is in full conformance with
|
||||
all provisions of Section 10 of RFC2026 [1].
|
||||
|
||||
Internet-Drafts are working documents of the Internet Engineering
|
||||
Task Force (IETF), its areas, and its working groups. Note that
|
||||
other groups may also distribute working documents as Internet-
|
||||
Drafts. Internet-Drafts are draft documents valid for a maximum of
|
||||
six months and may be updated, replaced, or obsoleted by other
|
||||
documents at any time. It is inappropriate to use Internet- Drafts
|
||||
as reference material or to cite them other than as "work in
|
||||
progress."
|
||||
The list of current Internet-Drafts can be accessed at
|
||||
http://www.ietf.org/ietf/1id-abstracts.txt
|
||||
The list of Internet-Draft Shadow Directories can be accessed at
|
||||
http://www.ietf.org/shadow.html.
|
||||
|
||||
|
||||
1. Abstract
|
||||
|
||||
This document describes the ExtendedPartialResponse, an element of
|
||||
LDAP v3 protocol which allows multiple responses to LDAP v3 extended
|
||||
requests. Extended partial responses are backward compatible with
|
||||
the existing LDAP v3 Extended Operation defined in [LDAPv3].
|
||||
|
||||
2. Conventions used in this document
|
||||
|
||||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
|
||||
this document are to be interpreted as described in [RFC2119].
|
||||
|
||||
|
||||
3. Motivation for the Extended Partial Response
|
||||
|
||||
The Extended Operation ([LDAPv3] Section 4.12) was defined in LDAP
|
||||
v3 to allow additional operations to be defined as part of the
|
||||
protocol without requiring a new revision of the protocol.
|
||||
|
||||
The LDAP v3 Extended Operation allows for a single extended response
|
||||
to each extended request, but this paradigm may not be sufficient
|
||||
for some directory operations. For instance, the LDAP search
|
||||
operation is a directory operation that is much more efficient when
|
||||
multiple partial responses are used to service a single request. The
|
||||
|
||||
LDAP v3 Extended Partial Response June, 2000
|
||||
|
||||
|
||||
extended partial response generalizes the current extended operation
|
||||
definition to give LDAP server implementers the ability to make use
|
||||
of a single-request-multiple-response paradigm for extended LDAP
|
||||
operations that require it or that would benefit from it.
|
||||
|
||||
4. Element of Protocol
|
||||
|
||||
The ExtendedPartialResponse is defined as
|
||||
|
||||
ExtendedPartialResponse ::= [APPLICATION 25] SEQUENCE {
|
||||
responseName [0] LDAPOID OPTIONAL,
|
||||
response [1] OCTET STRING OPTIONAL }
|
||||
|
||||
An LDAP server responds to an LDAP v3 ExtendedRequest with zero or
|
||||
more ExtendedPartialResponses followed by one ExtendedResponse. This
|
||||
ensures backward compatibility with existing LDAP extensions which
|
||||
do not make use of the ExtendedPartialResponse. As with all LDAP
|
||||
extensions, LDAP extensions that make use of the
|
||||
ExtendedPartialResponse have predefined syntax and semantics that
|
||||
are defined in RFCs or are private to a particular implementation.
|
||||
|
||||
5. Security Considerations
|
||||
|
||||
This draft describes an enhancement to the LDAP v3 protocol
|
||||
[LDAPv3]. All security considerations of [LDAPv3] apply to this
|
||||
draft, however it does not introduce any new security considerations
|
||||
to the LDAP v3 protocol.
|
||||
|
||||
6. References
|
||||
|
||||
[LDAPv3]
|
||||
Wahl, M., Howes, T., and S. Kille, "Lightweight Directory
|
||||
Access Protocol (v3)", RFC 2251, December 1997.
|
||||
|
||||
[ReqsKeywords]
|
||||
Scott Bradner. "Key Words for use in RFCs to Indicate
|
||||
Requirement Levels". RFC 2119.
|
||||
|
||||
|
||||
7. Acknowledgments
|
||||
|
||||
The author would like to acknowledge the readers of the LDAP
|
||||
Extensions working group mail list who responded to the suggestion
|
||||
that a multiple-response paradigm might be useful for LDAP extended
|
||||
requests. Special thanks go to two individuals: David Wilbur who
|
||||
first introduced the idea on the working group list, and Thomas
|
||||
Salter, who succinctly summarized the discussion and suggested the
|
||||
name ExtendedPartialResponse in his summary.
|
||||
|
||||
8. Author's Addresses
|
||||
|
||||
Roger Harrison
|
||||
Novell, Inc.
|
||||
|
||||
LDAP v3 Extended Partial Response June, 2000
|
||||
|
||||
|
||||
1800 S. Novell Place
|
||||
Provo, UT 84606
|
||||
+1 801 861 2642
|
||||
roger_harrison@novell.com
|
||||
|
||||
|
||||
Appendix A - Document Revision History
|
||||
|
||||
A.1 draft-rharrison-ldap-extPartResp-00.doc
|
||||
|
||||
Initial revision of draft.
|
||||
|
||||
A.2 draft-rharrison-ldap-extPartResp-01.doc
|
||||
|
||||
Changed responseName to be optional to align with [LDAPv3]
|
||||
definition of ExtendedResponse.
|
||||
|
||||
Full Copyright Statement
|
||||
|
||||
"Copyright (C) The Internet Society (date). All Rights Reserved.
|
||||
This document and translations of it may be copied and furnished to
|
||||
others, and derivative works that comment on or otherwise explain it
|
||||
or assist in its implmentation may be prepared, copied, published
|
||||
and distributed, in whole or in part, without restriction of any
|
||||
kind, provided that the above copyright notice and this paragraph
|
||||
are included on all such copies and derivative works. However, this
|
||||
document itself may not be modified in any way, such as by removing
|
||||
the copyright notice or references to the Internet Society or other
|
||||
Internet organizations, except as needed for the purpose of
|
||||
developing Internet standards in which case the procedures for
|
||||
copyrights defined in the Internet Standards process must be
|
||||
followed, or as required to translate it into languages other than
|
||||
English.
|
||||
|
||||
The limited permissions granted above are perpetual and will not be
|
||||
revoked by the Internet Society or its successors or assigns.
|
||||
|
||||
This document and the information contained herein is provided on an
|
||||
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
|
||||
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
|
||||
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
|
||||
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
|
@ -1326,57 +1326,6 @@ ldap_search_st LDAP_P(( /* deprecated */
|
|||
struct timeval *timeout,
|
||||
LDAPMessage **res ));
|
||||
|
||||
|
||||
/*
|
||||
* in ufn.c
|
||||
* (deprecated)
|
||||
*/
|
||||
LDAP_F( int )
|
||||
ldap_ufn_search_c LDAP_P(( /* deprecated */
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *ufn,
|
||||
char **attrs,
|
||||
int attrsonly,
|
||||
LDAPMessage **res,
|
||||
int (*cancelproc)( void *cl ),
|
||||
void *cancelparm ));
|
||||
|
||||
LDAP_F( int )
|
||||
ldap_ufn_search_ct LDAP_P(( /* deprecated */
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *ufn,
|
||||
char **attrs,
|
||||
int attrsonly,
|
||||
LDAPMessage **res,
|
||||
int (*cancelproc)( void *cl ),
|
||||
void *cancelparm,
|
||||
char *tag1,
|
||||
char *tag2,
|
||||
char *tag3 ));
|
||||
|
||||
LDAP_F( int )
|
||||
ldap_ufn_search_s LDAP_P(( /* deprecated */
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *ufn,
|
||||
char **attrs,
|
||||
int attrsonly,
|
||||
LDAPMessage **res ));
|
||||
|
||||
LDAP_F( LDAPFiltDesc *)
|
||||
ldap_ufn_setfilter LDAP_P(( /* deprecated */
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *fname ));
|
||||
|
||||
LDAP_F( void )
|
||||
ldap_ufn_setprefix LDAP_P(( /* deprecated */
|
||||
LDAP *ld,
|
||||
LDAP_CONST char *prefix ));
|
||||
|
||||
LDAP_F( int )
|
||||
ldap_ufn_timeout LDAP_P(( /* deprecated */
|
||||
void *tvparam ));
|
||||
|
||||
|
||||
/*
|
||||
* in unbind.c
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -148,6 +148,11 @@ LDAP_F (int) ldap_pvt_sasl_install LDAP_P(( struct sockbuf *, void * ));
|
|||
|
||||
#define LDAP_PVT_SASL_LOCAL_SSF 71 /* SSF for Unix Domain Sockets */
|
||||
|
||||
struct ldap;
|
||||
|
||||
LDAP_F (int) ldap_open_internal_connection LDAP_P((
|
||||
struct ldap **ldp, ber_socket_t *fdp ));
|
||||
|
||||
/* search.c */
|
||||
LDAP_F( char * )
|
||||
ldap_pvt_find_wildcard LDAP_P(( const char *s ));
|
||||
|
|
@ -163,21 +168,21 @@ LDAP_F( char * )
|
|||
ldap_pvt_str2lower LDAP_P(( char *str ));
|
||||
|
||||
/* tls.c */
|
||||
struct ldapoptions;
|
||||
struct ldap;
|
||||
|
||||
LDAP_F (int) ldap_pvt_tls_init LDAP_P(( void ));
|
||||
LDAP_F (int) ldap_pvt_tls_connect LDAP_P(( struct ldap *ld, Sockbuf *sb, void *ctx_arg ));
|
||||
LDAP_F (int) ldap_pvt_tls_connect LDAP_P(( struct ldap *ld,
|
||||
Sockbuf *sb, void *ctx_arg ));
|
||||
LDAP_F (int) ldap_pvt_tls_accept LDAP_P(( Sockbuf *sb, void *ctx_arg ));
|
||||
LDAP_F (void *) ldap_pvt_tls_sb_handle LDAP_P(( Sockbuf *sb ));
|
||||
LDAP_F (void *) ldap_pvt_tls_get_handle LDAP_P(( struct ldap *ld ));
|
||||
LDAP_F (const char *) ldap_pvt_tls_get_peer LDAP_P(( void *handle ));
|
||||
LDAP_F (char *) ldap_pvt_tls_get_peer LDAP_P(( void *handle ));
|
||||
LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *handle ));
|
||||
LDAP_F (int) ldap_pvt_tls_inplace LDAP_P(( Sockbuf *sb ));
|
||||
LDAP_F (int) ldap_pvt_tls_start LDAP_P(( struct ldap *ld, Sockbuf *sb, void *ctx_arg ));
|
||||
|
||||
LDAP_F (int) ldap_pvt_tls_get_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
|
||||
LDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldapoptions *lo, int option, void *arg ));
|
||||
LDAP_F (int) ldap_pvt_tls_start LDAP_P(( struct ldap *ld,
|
||||
Sockbuf *sb, void *ctx_arg ));
|
||||
LDAP_F (int) ldap_pvt_tls_get_option LDAP_P(( struct ldap *ld,
|
||||
int option, void *arg ));
|
||||
LDAP_F (int) ldap_pvt_tls_set_option LDAP_P(( struct ldap *ld,
|
||||
int option, void *arg ));
|
||||
|
||||
/*
|
||||
* UTF-8 (in utf-8.c)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ PROGRAMS = apitest ltest ttest
|
|||
|
||||
SRCS = bind.c open.c result.c error.c compare.c search.c \
|
||||
controls.c messages.c references.c extended.c cyrus.c \
|
||||
modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c \
|
||||
modify.c add.c modrdn.c delete.c abandon.c cache.c \
|
||||
getfilter.c sasl.c sbind.c kbind.c unbind.c friendly.c \
|
||||
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
|
||||
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
||||
|
|
@ -21,7 +21,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
|
|||
utf-8.c
|
||||
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||
controls.lo messages.lo references.lo extended.lo cyrus.lo \
|
||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
|
||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo cache.lo \
|
||||
getfilter.lo sasl.lo sbind.lo kbind.lo unbind.lo friendly.lo \
|
||||
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
|
||||
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
|
||||
|
|
|
|||
|
|
@ -56,8 +56,13 @@ ldap_abandon_ext(
|
|||
LDAPControl **sctrls,
|
||||
LDAPControl **cctrls )
|
||||
{
|
||||
int rc;
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
return do_abandon( ld, msgid, msgid, sctrls, cctrls );
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +82,7 @@ int
|
|||
ldap_abandon( LDAP *ld, int msgid )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 );
|
||||
return do_abandon( ld, msgid, msgid, NULL, NULL ) == LDAP_SUCCESS
|
||||
return ldap_abandon_ext( ld, msgid, NULL, NULL ) == LDAP_SUCCESS
|
||||
? 0 : -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,10 @@ ldap_add_ext(
|
|||
assert( dn != NULL );
|
||||
assert( msgidp != NULL );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
/* create a message to send */
|
||||
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ ldap_compare_ext(
|
|||
LDAPControl **cctrls,
|
||||
int *msgidp )
|
||||
{
|
||||
int rc;
|
||||
BerElement *ber;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_compare\n", 0, 0, 0 );
|
||||
|
|
@ -61,6 +62,10 @@ ldap_compare_ext(
|
|||
assert( attr != NULL );
|
||||
assert( msgidp != NULL );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
/* create a message to send */
|
||||
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
|
||||
return( LDAP_NO_MEMORY );
|
||||
|
|
|
|||
|
|
@ -441,3 +441,34 @@ ldap_create_control(
|
|||
*ctrlp = ctrl;
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* check for critical client controls and bitch if present
|
||||
* if we ever support critical controls, we'll have to
|
||||
* find a means for maintaining per API call control
|
||||
* information.
|
||||
*/
|
||||
int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
|
||||
{
|
||||
LDAPControl *const *c;
|
||||
|
||||
assert( ld != NULL );
|
||||
|
||||
if( ctrls == NULL ) {
|
||||
/* use default server controls */
|
||||
ctrls = ld->ld_cctrls;
|
||||
}
|
||||
|
||||
if( ctrls == NULL || *ctrls == NULL ) {
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
for( c = ctrls ; *c != NULL; c++ ) {
|
||||
if( (*c)->ldctl_iscritical ) {
|
||||
ld->ld_errno = LDAP_NOT_SUPPORTED;
|
||||
return ld->ld_errno;
|
||||
}
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ ldap_int_sasl_open(
|
|||
return ld->ld_errno;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: %s\n",
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: host=%s\n",
|
||||
host, 0, 0 );
|
||||
|
||||
lc->lconn_sasl_ctx = ctx;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ ldap_delete_ext(
|
|||
LDAPControl **cctrls,
|
||||
int *msgidp )
|
||||
{
|
||||
int rc;
|
||||
BerElement *ber;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_delete\n", 0, 0, 0 );
|
||||
|
|
@ -54,6 +55,10 @@ ldap_delete_ext(
|
|||
assert( dn != NULL );
|
||||
assert( msgidp != NULL );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
/* create a message to send */
|
||||
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
|
|
|
|||
|
|
@ -54,88 +54,41 @@ ldap_get_dn( LDAP *ld, LDAPMessage *entry )
|
|||
char *
|
||||
ldap_dn2ufn( LDAP_CONST char *dn )
|
||||
{
|
||||
char *p, *ufn, *r;
|
||||
int state;
|
||||
char *ufn;
|
||||
char **vals;
|
||||
int i;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
|
||||
|
||||
/* produces completely untyped UFNs */
|
||||
|
||||
if( dn == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( ( p = ldap_utf8_strpbrk( dn, "=" ) ) == NULL ) {
|
||||
return( LDAP_STRDUP( dn ) );
|
||||
vals = ldap_explode_dn( dn , 0 );
|
||||
if( vals == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
ufn = LDAP_STRDUP( ++p );
|
||||
|
||||
if( ufn == NULL ) return NULL;
|
||||
for ( i = 0; vals[i]; i++ ) {
|
||||
char **rvals;
|
||||
|
||||
#define INQUOTE 1
|
||||
#define OUTQUOTE 2
|
||||
state = OUTQUOTE;
|
||||
for ( p = ufn, r = ufn; *p; LDAP_UTF8_INCR(p) ) {
|
||||
switch ( *p ) {
|
||||
case '\\':
|
||||
if ( p[1] != '\0' ) {
|
||||
*r++ = '\\';
|
||||
LDAP_UTF8_COPY(r,++p);
|
||||
LDAP_UTF8_INCR(r);
|
||||
}
|
||||
break;
|
||||
|
||||
case '"':
|
||||
if ( state == INQUOTE )
|
||||
state = OUTQUOTE;
|
||||
else
|
||||
state = INQUOTE;
|
||||
*r++ = *p;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
case ',':
|
||||
if ( state == OUTQUOTE )
|
||||
*r++ = ',';
|
||||
else
|
||||
*r++ = *p;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
if ( state == INQUOTE ) {
|
||||
*r++ = *p;
|
||||
} else {
|
||||
char *rsave = r;
|
||||
|
||||
*r = '\0';
|
||||
LDAP_UTF8_DECR( r );
|
||||
|
||||
while ( !ldap_utf8_isspace( r )
|
||||
&& *r != ';' && *r != ',' && r > ufn )
|
||||
{
|
||||
LDAP_UTF8_DECR( r );
|
||||
}
|
||||
LDAP_UTF8_INCR( r );
|
||||
|
||||
if ( strcasecmp( r, "c" )
|
||||
&& strcasecmp( r, "o" )
|
||||
&& strcasecmp( r, "ou" )
|
||||
&& strcasecmp( r, "st" )
|
||||
&& strcasecmp( r, "l" )
|
||||
&& strcasecmp( r, "cn" ) ) {
|
||||
r = rsave;
|
||||
*r++ = '=';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LDAP_UTF8_COPY(r, p);
|
||||
LDAP_UTF8_INCR(r);
|
||||
break;
|
||||
rvals = ldap_explode_rdn( vals[i] , 1 );
|
||||
if ( rvals == NULL ) {
|
||||
LDAP_VFREE( vals );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*r = '\0';
|
||||
|
||||
return( ufn );
|
||||
LDAP_FREE( vals[i] );
|
||||
vals[i] = ldap_charray2str( rvals, " + " );
|
||||
LDAP_VFREE( rvals );
|
||||
}
|
||||
|
||||
ufn = ldap_charray2str( vals, ", " );
|
||||
|
||||
LDAP_VFREE( vals );
|
||||
return ufn;
|
||||
}
|
||||
|
||||
char **
|
||||
|
|
@ -237,6 +190,9 @@ ldap_dcedn2dn( LDAP_CONST char *dce )
|
|||
return dn;
|
||||
}
|
||||
|
||||
#define INQUOTE 1
|
||||
#define OUTQUOTE 2
|
||||
|
||||
static char **
|
||||
explode_name( const char *name, int notypes, int is_type )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ struct ldapoptions ldap_int_global_options =
|
|||
#define ATTR_INT 2
|
||||
#define ATTR_KV 3
|
||||
#define ATTR_STRING 4
|
||||
#define ATTR_URIS 5
|
||||
#define ATTR_OPTION 5
|
||||
|
||||
#define ATTR_SASL 6
|
||||
#define ATTR_TLS 7
|
||||
|
|
@ -63,8 +63,8 @@ static const struct ol_attribute {
|
|||
offsetof(struct ldapoptions, ldo_defbase)},
|
||||
{0, ATTR_INT, "PORT", NULL, /* deprecated */
|
||||
offsetof(struct ldapoptions, ldo_defport)},
|
||||
{0, ATTR_URIS, "HOST", NULL, 1}, /* deprecated */
|
||||
{0, ATTR_URIS, "URI", NULL, 0}, /* replaces HOST/URI */
|
||||
{0, ATTR_OPTION, "HOST", NULL, LDAP_OPT_HOST_NAME}, /* deprecated */
|
||||
{0, ATTR_OPTION, "URI", NULL, LDAP_OPT_URI}, /* replaces HOST/PORT */
|
||||
{0, ATTR_BOOL, "REFERRALS", NULL, LDAP_BOOL_REFERRALS},
|
||||
{0, ATTR_BOOL, "RESTART", NULL, LDAP_BOOL_RESTART},
|
||||
|
||||
|
|
@ -211,12 +211,8 @@ static void openldap_ldap_init_w_conf(
|
|||
if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
|
||||
* (char**) p = LDAP_STRDUP(opt);
|
||||
break;
|
||||
case ATTR_URIS:
|
||||
if (attrs[i].offset == 0) {
|
||||
ldap_set_option( NULL, LDAP_OPT_URI, opt );
|
||||
} else {
|
||||
ldap_set_option( NULL, LDAP_OPT_HOST_NAME, opt );
|
||||
}
|
||||
case ATTR_OPTION:
|
||||
ldap_set_option( NULL, attrs[i].offset, opt );
|
||||
break;
|
||||
case ATTR_SASL:
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
|
|
@ -351,12 +347,8 @@ static void openldap_ldap_init_w_env(
|
|||
* (char**) p = LDAP_STRDUP(value);
|
||||
}
|
||||
break;
|
||||
case ATTR_URIS:
|
||||
if (attrs[i].offset == 0) {
|
||||
ldap_set_option( NULL, LDAP_OPT_URI, value );
|
||||
} else {
|
||||
ldap_set_option( NULL, LDAP_OPT_HOST_NAME, value );
|
||||
}
|
||||
case ATTR_OPTION:
|
||||
ldap_set_option( NULL, attrs[i].offset, value );
|
||||
break;
|
||||
case ATTR_SASL:
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
|
|
@ -418,12 +410,7 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
|
|||
SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
gopts->ldo_tls_ctx = NULL;
|
||||
#endif
|
||||
|
||||
gopts->ldo_valid = LDAP_INITIALIZED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,10 @@ struct ldapoptions {
|
|||
ber_int_t ldo_timelimit;
|
||||
ber_int_t ldo_sizelimit;
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
int ldo_tls_mode;
|
||||
#endif
|
||||
|
||||
LDAPURLDesc *ldo_defludp;
|
||||
int ldo_defport;
|
||||
char* ldo_defbase;
|
||||
|
|
@ -146,32 +150,22 @@ struct ldapoptions {
|
|||
/* LDAP rebind callback function */
|
||||
LDAP_REBIND_PROC *ldo_rebindproc;
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
/* tls context */
|
||||
void *ldo_tls_ctx;
|
||||
int ldo_tls_mode;
|
||||
#endif
|
||||
LDAP_BOOLEANS ldo_booleans; /* boolean options */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* structure for tracking LDAP server host, ports, DNs, etc.
|
||||
*/
|
||||
typedef struct ldap_server {
|
||||
char *lsrv_host;
|
||||
char *lsrv_dn; /* if NULL, use default */
|
||||
int lsrv_port;
|
||||
struct ldap_server *lsrv_next;
|
||||
} LDAPServer;
|
||||
|
||||
|
||||
/*
|
||||
* structure for representing an LDAP server connection
|
||||
*/
|
||||
typedef struct ldap_conn {
|
||||
Sockbuf *lconn_sb;
|
||||
#ifdef HAVE_TLS
|
||||
/* tls context */
|
||||
void *lconn_tls_ctx;
|
||||
#endif
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
void *lconn_sasl_ctx;
|
||||
#endif
|
||||
int lconn_refcnt;
|
||||
time_t lconn_lastused; /* time */
|
||||
int lconn_rebind_inprogress; /* set if rebind in progress */
|
||||
|
|
@ -184,8 +178,9 @@ typedef struct ldap_conn {
|
|||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
|
||||
char *lconn_krbinstance;
|
||||
#endif
|
||||
BerElement *lconn_ber; /* ber receiving on this conn. */
|
||||
|
||||
struct ldap_conn *lconn_next;
|
||||
BerElement *lconn_ber;/* ber receiving on this conn. */
|
||||
} LDAPConn;
|
||||
|
||||
|
||||
|
|
@ -269,9 +264,6 @@ struct ldap {
|
|||
|
||||
#define ld_version ld_options.ldo_version
|
||||
|
||||
char *ld_host;
|
||||
int ld_port;
|
||||
|
||||
unsigned short ld_lberoptions;
|
||||
|
||||
LDAPFiltDesc *ld_filtd; /* from getfilter for ufn searches */
|
||||
|
|
@ -373,6 +365,9 @@ LDAP_F (int) ldap_int_put_controls LDAP_P((
|
|||
LDAPControl *const *ctrls,
|
||||
BerElement *ber ));
|
||||
|
||||
LDAP_F (int) ldap_int_client_controls LDAP_P((
|
||||
LDAP *ld,
|
||||
LDAPControl **ctrlp ));
|
||||
|
||||
/*
|
||||
* in dsparse.c
|
||||
|
|
@ -408,10 +403,11 @@ LDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb,
|
|||
int proto, const char *host, unsigned long address, int port,
|
||||
int async );
|
||||
|
||||
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
|
||||
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) || \
|
||||
defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
|
||||
LDAP_V (char *) ldap_int_hostname;
|
||||
LDAP_F (char *) ldap_host_connected_to( Sockbuf *sb );
|
||||
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
|
||||
#endif
|
||||
|
||||
LDAP_F (void) ldap_int_ip_init( void );
|
||||
LDAP_F (int) do_ldap_select( LDAP *ld, struct timeval *timeout );
|
||||
|
|
@ -540,7 +536,7 @@ LDAP_F (int) ldap_int_sasl_config LDAP_P(( struct ldapoptions *lo,
|
|||
int option, const char *arg ));
|
||||
|
||||
LDAP_F (int) ldap_int_sasl_bind LDAP_P((
|
||||
struct ldap *ld,
|
||||
LDAP *ld,
|
||||
const char *,
|
||||
const char *,
|
||||
LDAPControl **, LDAPControl **,
|
||||
|
|
@ -553,7 +549,11 @@ LDAP_F (int) ldap_int_sasl_bind LDAP_P((
|
|||
/*
|
||||
* in tls.c
|
||||
*/
|
||||
LDAP_F (int) ldap_int_tls_config LDAP_P(( struct ldapoptions *lo, int option, const char *arg ));
|
||||
LDAP_F (int) ldap_int_tls_config LDAP_P(( LDAP *ld,
|
||||
int option, const char *arg ));
|
||||
|
||||
LDAP_F (int) ldap_int_tls_start LDAP_P(( LDAP *ld,
|
||||
LDAPConn *conn ));
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,10 @@ ldap_modify_ext( LDAP *ld,
|
|||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
/* create a message to send */
|
||||
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
|
||||
return( LDAP_NO_MEMORY );
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ ldap_rename(
|
|||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_rename\n", 0, 0, 0 );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
/* create a message to send */
|
||||
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
|
||||
return( LDAP_NO_MEMORY );
|
||||
|
|
|
|||
|
|
@ -54,9 +54,11 @@ ldap_open( LDAP_CONST char *host, int port )
|
|||
int rc;
|
||||
LDAP *ld;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_open(%s, %d)\n",
|
||||
host, port, 0 );
|
||||
|
||||
if (( ld = ldap_init( host, port )) == NULL ) {
|
||||
ld = ldap_init( host, port );
|
||||
if ( ld == NULL ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
|
|
@ -64,13 +66,13 @@ ldap_open( LDAP_CONST char *host, int port )
|
|||
|
||||
if( rc < 0 ) {
|
||||
ldap_ld_free( ld, 0, NULL, NULL );
|
||||
return( NULL );
|
||||
ld = NULL;
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
|
||||
( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_open: %s\n",
|
||||
ld == NULL ? "succeeded" : "failed", 0, 0 );
|
||||
|
||||
return( ld );
|
||||
return ld;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -329,14 +331,10 @@ ldap_int_open_connection(
|
|||
if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ||
|
||||
strcmp( srv->lud_scheme, "ldaps" ) == 0 )
|
||||
{
|
||||
LDAPConn *savedefconn = ld->ld_defconn;
|
||||
++conn->lconn_refcnt; /* avoid premature free */
|
||||
ld->ld_defconn = conn;
|
||||
|
||||
rc = ldap_pvt_tls_start( ld, conn->lconn_sb,
|
||||
ld->ld_options.ldo_tls_ctx );
|
||||
rc = ldap_int_tls_start( ld, conn );
|
||||
|
||||
ld->ld_defconn = savedefconn;
|
||||
--conn->lconn_refcnt;
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
|
|
|
|||
|
|
@ -281,12 +281,14 @@ ldap_get_option(
|
|||
|
||||
default:
|
||||
#ifdef HAVE_TLS
|
||||
if ( ldap_pvt_tls_get_option((struct ldapoptions *)lo, option, outvalue ) == 0 )
|
||||
return LDAP_OPT_SUCCESS;
|
||||
if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) {
|
||||
return LDAP_OPT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
if ( ldap_int_sasl_get_option(ld, option, outvalue ) == 0 )
|
||||
return LDAP_OPT_SUCCESS;
|
||||
if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) {
|
||||
return LDAP_OPT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
/* bad param */
|
||||
break;
|
||||
|
|
@ -579,7 +581,7 @@ ldap_set_option(
|
|||
|
||||
default:
|
||||
#ifdef HAVE_TLS
|
||||
if ( ldap_pvt_tls_set_option( lo, option, (void *)invalue ) == 0 )
|
||||
if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
|
||||
return LDAP_OPT_SUCCESS;
|
||||
#endif
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
|
|||
struct hostent *hp = NULL;
|
||||
char *ha_buf=NULL, *p, *q;
|
||||
|
||||
osip_debug(ld, "ldap_connect_to_host\n",0,0,0);
|
||||
osip_debug(ld, "ldap_connect_to_host: %s\n",host,0,0);
|
||||
|
||||
if (host != NULL) {
|
||||
#if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
|
||||
|
|
@ -423,8 +423,8 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) \
|
||||
|| defined( HAVE_TLS ) || defined( HAVE_CYRUS_SASL )
|
||||
#if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND ) || \
|
||||
defined( HAVE_CYRUS_SASL )
|
||||
char *
|
||||
ldap_host_connected_to( Sockbuf *sb )
|
||||
{
|
||||
|
|
@ -510,7 +510,7 @@ ldap_host_connected_to( Sockbuf *sb )
|
|||
LDAP_FREE( ha_buf );
|
||||
return host;
|
||||
}
|
||||
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND || HAVE_TLS */
|
||||
#endif
|
||||
|
||||
|
||||
/* for UNIX */
|
||||
|
|
|
|||
|
|
@ -95,8 +95,8 @@ ldap_send_initial_request(
|
|||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"ldap_delayed_open successful, ld_host is %s\n",
|
||||
( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
|
||||
"ldap_open_defconn: successful\n",
|
||||
0, 0, 0 );
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ ldap_sasl_bind(
|
|||
assert( LDAP_VALID( ld ) );
|
||||
assert( msgidp != NULL );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
if( msgidp == NULL ) {
|
||||
ld->ld_errno = LDAP_PARAM_ERROR;
|
||||
return ld->ld_errno;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ ldap_search_ext(
|
|||
int sizelimit,
|
||||
int *msgidp )
|
||||
{
|
||||
int rc;
|
||||
BerElement *ber;
|
||||
int timelimit;
|
||||
|
||||
|
|
@ -99,6 +100,10 @@ ldap_search_ext(
|
|||
assert( ld != NULL );
|
||||
assert( LDAP_VALID( ld ) );
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
/*
|
||||
* if timeout is provided, both tv_sec and tv_usec must
|
||||
* be non-zero
|
||||
|
|
|
|||
|
|
@ -599,37 +599,6 @@ main( int argc, char **argv )
|
|||
timeout.tv_sec = atoi( line );
|
||||
break;
|
||||
|
||||
case 'U': /* set ufn search prefix */
|
||||
getline( line, sizeof(line), stdin, "ufn prefix? " );
|
||||
ldap_ufn_setprefix( ld, line );
|
||||
break;
|
||||
|
||||
case 'u': /* user friendly search w/optional timeout */
|
||||
getline( dn, sizeof(dn), stdin, "ufn? " );
|
||||
strcat( dn, dnsuffix );
|
||||
types = get_list( "attrs to return? " );
|
||||
getline( line, sizeof(line), stdin,
|
||||
"attrsonly (0=attrs&values, 1=attrs only)? " );
|
||||
attrsonly = atoi( line );
|
||||
|
||||
if ( command2 == 't' ) {
|
||||
id = ldap_ufn_search_c( ld, dn, types,
|
||||
attrsonly, &res, ldap_ufn_timeout,
|
||||
&timeout );
|
||||
} else {
|
||||
id = ldap_ufn_search_s( ld, dn, types,
|
||||
attrsonly, &res );
|
||||
}
|
||||
if ( res == NULL )
|
||||
ldap_perror( ld, "ldap_ufn_search" );
|
||||
else {
|
||||
printf( "\nresult: err %d\n", id );
|
||||
handle_result( ld, res );
|
||||
res = NULL;
|
||||
}
|
||||
free_list( types );
|
||||
break;
|
||||
|
||||
case 'l': /* URL search */
|
||||
getline( line, sizeof(line), stdin,
|
||||
"attrsonly (0=attrs&values, 1=attrs only)? " );
|
||||
|
|
|
|||
|
|
@ -553,16 +553,19 @@ BIO_METHOD ldap_pvt_sb_bio_method =
|
|||
* and call again.
|
||||
*/
|
||||
|
||||
int
|
||||
ldap_pvt_tls_connect( LDAP *ld, Sockbuf *sb, void *ctx_arg )
|
||||
static int
|
||||
ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
|
||||
{
|
||||
Sockbuf *sb = conn->lconn_sb;
|
||||
void *ctx = ld->ld_defconn->lconn_tls_ctx;
|
||||
|
||||
int err;
|
||||
SSL *ssl;
|
||||
|
||||
if ( HAS_TLS( sb ) ) {
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
|
||||
} else {
|
||||
ssl = alloc_handle( ctx_arg );
|
||||
ssl = alloc_handle( ctx );
|
||||
if ( ssl == NULL )
|
||||
return -1;
|
||||
#ifdef LDAP_DEBUG
|
||||
|
|
@ -652,7 +655,7 @@ ldap_pvt_tls_inplace ( Sockbuf *sb )
|
|||
}
|
||||
|
||||
void *
|
||||
ldap_pvt_tls_sb_handle( Sockbuf *sb )
|
||||
ldap_pvt_tls_sb_ctx( Sockbuf *sb )
|
||||
{
|
||||
void *p;
|
||||
|
||||
|
|
@ -664,12 +667,6 @@ ldap_pvt_tls_sb_handle( Sockbuf *sb )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
ldap_pvt_tls_get_handle( LDAP *ld )
|
||||
{
|
||||
return ldap_pvt_tls_sb_handle( ld->ld_sb );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_pvt_tls_get_strength( void *s )
|
||||
{
|
||||
|
|
@ -680,7 +677,7 @@ ldap_pvt_tls_get_strength( void *s )
|
|||
}
|
||||
|
||||
|
||||
const char *
|
||||
char *
|
||||
ldap_pvt_tls_get_peer( void *s )
|
||||
{
|
||||
X509 *x;
|
||||
|
|
@ -698,12 +695,33 @@ ldap_pvt_tls_get_peer( void *s )
|
|||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_pvt_tls_get_peer_dn( void *s )
|
||||
{
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
char buf[2048], *p, *dn;
|
||||
|
||||
x = SSL_get_peer_certificate((SSL *)s);
|
||||
|
||||
if (!x) return NULL;
|
||||
|
||||
xn = X509_get_subject_name(x);
|
||||
p = X509_NAME_oneline(xn, buf, sizeof(buf));
|
||||
|
||||
dn = ldap_dcedn2dn( p );
|
||||
|
||||
X509_free(x);
|
||||
return dn;
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_pvt_tls_get_peer_hostname( void *s )
|
||||
{
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
char buf[2048], *p;
|
||||
int ret;
|
||||
|
||||
x = SSL_get_peer_certificate((SSL *)s);
|
||||
|
||||
|
|
@ -712,7 +730,8 @@ ldap_pvt_tls_get_peer_hostname( void *s )
|
|||
|
||||
xn = X509_get_subject_name(x);
|
||||
|
||||
if ( X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1 ) {
|
||||
ret = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf));
|
||||
if( ret == -1 ) {
|
||||
X509_free(x);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -745,7 +764,7 @@ ldap_pvt_tls_get_peer_issuer( void *s )
|
|||
}
|
||||
|
||||
int
|
||||
ldap_int_tls_config( struct ldapoptions *lo, int option, const char *arg )
|
||||
ldap_int_tls_config( LDAP *ld, int option, const char *arg )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -756,11 +775,13 @@ ldap_int_tls_config( struct ldapoptions *lo, int option, const char *arg )
|
|||
case LDAP_OPT_X_TLS_KEYFILE:
|
||||
case LDAP_OPT_X_TLS_RANDOM_FILE:
|
||||
return ldap_pvt_tls_set_option( NULL, option, (void *) arg );
|
||||
|
||||
case LDAP_OPT_X_TLS_REQUIRE_CERT:
|
||||
i = ( ( strcasecmp( arg, "on" ) == 0 ) ||
|
||||
( strcasecmp( arg, "yes" ) == 0) ||
|
||||
( strcasecmp( arg, "true" ) == 0 ) );
|
||||
return ldap_pvt_tls_set_option( NULL, option, (void *) &i );
|
||||
|
||||
case LDAP_OPT_X_TLS:
|
||||
i = -1;
|
||||
if ( strcasecmp( arg, "never" ) == 0 )
|
||||
|
|
@ -773,8 +794,10 @@ ldap_int_tls_config( struct ldapoptions *lo, int option, const char *arg )
|
|||
i = LDAP_OPT_X_TLS_TRY ;
|
||||
if ( strcasecmp( arg, "hard" ) == 0 )
|
||||
i = LDAP_OPT_X_TLS_HARD ;
|
||||
if (i >= 0)
|
||||
return ldap_pvt_tls_set_option( lo, option, &i );
|
||||
|
||||
if (i >= 0) {
|
||||
return ldap_pvt_tls_set_option( ld, option, &i );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -782,17 +805,35 @@ ldap_int_tls_config( struct ldapoptions *lo, int option, const char *arg )
|
|||
}
|
||||
|
||||
int
|
||||
ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg )
|
||||
ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
|
||||
{
|
||||
struct ldapoptions *lo;
|
||||
|
||||
/* Get pointer to global option structure */
|
||||
lo = LDAP_INT_GLOBAL_OPT();
|
||||
if (NULL == lo) {
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
if(ld != NULL) {
|
||||
assert( LDAP_VALID( ld ) );
|
||||
|
||||
if( !LDAP_VALID( ld ) ) {
|
||||
return LDAP_OPT_ERROR;
|
||||
}
|
||||
|
||||
lo = &ld->ld_options;
|
||||
}
|
||||
|
||||
switch( option ) {
|
||||
case LDAP_OPT_X_TLS:
|
||||
*(int *)arg = lo->ldo_tls_mode;
|
||||
break;
|
||||
case LDAP_OPT_X_TLS_CERT:
|
||||
if ( lo == NULL )
|
||||
case LDAP_OPT_X_TLS_CTX:
|
||||
if ( ld == NULL )
|
||||
*(void **)arg = (void *) tls_def_ctx;
|
||||
else
|
||||
*(void **)arg = lo->ldo_tls_ctx;
|
||||
*(void **)arg = ld->ld_defconn->lconn_tls_ctx;
|
||||
break;
|
||||
case LDAP_OPT_X_TLS_CACERTFILE:
|
||||
*(char **)arg = tls_opt_cacertfile ?
|
||||
|
|
@ -823,8 +864,26 @@ ldap_pvt_tls_get_option( struct ldapoptions *lo, int option, void *arg )
|
|||
}
|
||||
|
||||
int
|
||||
ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
|
||||
ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
|
||||
{
|
||||
struct ldapoptions *lo;
|
||||
|
||||
/* Get pointer to global option structure */
|
||||
lo = LDAP_INT_GLOBAL_OPT();
|
||||
if (NULL == lo) {
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
if(ld != NULL) {
|
||||
assert( LDAP_VALID( ld ) );
|
||||
|
||||
if( !LDAP_VALID( ld ) ) {
|
||||
return LDAP_OPT_ERROR;
|
||||
}
|
||||
|
||||
lo = &ld->ld_options;
|
||||
}
|
||||
|
||||
switch( option ) {
|
||||
case LDAP_OPT_X_TLS:
|
||||
switch( *(int *) arg ) {
|
||||
|
|
@ -841,12 +900,12 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
|
|||
}
|
||||
return -1;
|
||||
|
||||
case LDAP_OPT_X_TLS_CERT:
|
||||
if ( lo == NULL ) {
|
||||
case LDAP_OPT_X_TLS_CTX:
|
||||
if ( ld == NULL ) {
|
||||
tls_def_ctx = (SSL_CTX *) arg;
|
||||
|
||||
} else {
|
||||
lo->ldo_tls_ctx = arg;
|
||||
ld->ld_defconn->lconn_tls_ctx = arg;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -890,9 +949,13 @@ ldap_pvt_tls_set_option( struct ldapoptions *lo, int option, void *arg )
|
|||
}
|
||||
|
||||
int
|
||||
ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg )
|
||||
ldap_int_tls_start ( LDAP *ld, LDAPConn *conn )
|
||||
{
|
||||
char *peer_cert_cn, *peer_hostname;
|
||||
Sockbuf *sb = conn->lconn_sb;
|
||||
char *host = conn->lconn_server->lud_host;
|
||||
void *ctx = ld->ld_defconn->lconn_tls_ctx;
|
||||
|
||||
char *peer_cert_cn;
|
||||
void *ssl;
|
||||
|
||||
(void) ldap_pvt_tls_init();
|
||||
|
|
@ -900,14 +963,17 @@ ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg )
|
|||
/*
|
||||
* Fortunately, the lib uses blocking io...
|
||||
*/
|
||||
if ( ldap_pvt_tls_connect( ld, sb, ctx_arg ) < 0 ) {
|
||||
if ( ldap_int_tls_connect( ld, conn ) < 0 ) {
|
||||
return LDAP_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
ssl = (void *) ldap_pvt_tls_sb_handle( sb );
|
||||
ssl = (void *) ldap_pvt_tls_sb_ctx( sb );
|
||||
assert( ssl != NULL );
|
||||
|
||||
/*
|
||||
* compare hostname of server with name in certificate
|
||||
* compare host with name in certificate
|
||||
*/
|
||||
|
||||
peer_cert_cn = ldap_pvt_tls_get_peer_hostname( ssl );
|
||||
if ( !peer_cert_cn ) {
|
||||
/* could not get hostname from peer certificate */
|
||||
|
|
@ -916,30 +982,17 @@ ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg )
|
|||
0, 0, 0 );
|
||||
return LDAP_LOCAL_ERROR;
|
||||
}
|
||||
|
||||
peer_hostname = ldap_host_connected_to( sb );
|
||||
if ( !peer_hostname ) {
|
||||
/* could not lookup hostname */
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"TLS: unable to reverse lookup peer hostname.\n",
|
||||
0, 0, 0 );
|
||||
LDAP_FREE( peer_cert_cn );
|
||||
return LDAP_LOCAL_ERROR;
|
||||
}
|
||||
|
||||
if ( strcasecmp(peer_hostname, peer_cert_cn) != 0 ) {
|
||||
if ( strcasecmp( host, peer_cert_cn ) != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
|
||||
"common name in certificate (%s).\n",
|
||||
peer_hostname, peer_cert_cn, 0 );
|
||||
host, peer_cert_cn, 0 );
|
||||
LDAP_FREE( peer_cert_cn );
|
||||
LDAP_FREE( peer_hostname );
|
||||
return LDAP_CONNECT_ERROR;
|
||||
|
||||
} else {
|
||||
LDAP_FREE( peer_cert_cn );
|
||||
LDAP_FREE( peer_hostname );
|
||||
}
|
||||
|
||||
LDAP_FREE( peer_cert_cn );
|
||||
|
||||
/*
|
||||
* set SASL properties to TLS ssf and authid
|
||||
*/
|
||||
|
|
@ -1128,12 +1181,13 @@ ldap_start_tls_s ( LDAP *ld,
|
|||
LDAPControl **serverctrls,
|
||||
LDAPControl **clientctrls )
|
||||
{
|
||||
#ifdef HAVE_TLS
|
||||
int rc;
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
char *rspoid = NULL;
|
||||
struct berval *rspdata = NULL;
|
||||
|
||||
/* XXYYZ: this initiates operaton only on default connection! */
|
||||
/* XXYYZ: this initiates operation only on default connection! */
|
||||
|
||||
if ( ldap_pvt_tls_inplace( ld->ld_sb ) != 0 ) {
|
||||
return LDAP_LOCAL_ERROR;
|
||||
|
|
@ -1153,10 +1207,10 @@ ldap_start_tls_s ( LDAP *ld,
|
|||
ber_bvfree( rspdata );
|
||||
}
|
||||
|
||||
rc = ldap_pvt_tls_start( ld, ld->ld_sb, ld->ld_options.ldo_tls_ctx );
|
||||
return rc;
|
||||
rc = ldap_int_tls_start( ld, ld->ld_defconn );
|
||||
#else
|
||||
return LDAP_NOT_SUPPORTED;
|
||||
rc = LDAP_NOT_SUPPORTED;
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,498 +0,0 @@
|
|||
/* $OpenLDAP$ */
|
||||
/*
|
||||
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
|
||||
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
||||
*/
|
||||
/* Portions
|
||||
* Copyright (c) 1990 Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ufn.c
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/stdlib.h>
|
||||
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
|
||||
#include "ldap-int.h"
|
||||
#include "ldap_defaults.h"
|
||||
|
||||
typedef int (*cancelptype) LDAP_P(( void *cancelparm ));
|
||||
|
||||
/* local functions */
|
||||
static int ldap_ufn_search_ctx LDAP_P(( LDAP *ld, char **ufncomp, int ncomp,
|
||||
char *prefix, char **attrs, int attrsonly, LDAPMessage **res,
|
||||
cancelptype cancelproc, void *cancelparm, char *tag1, char *tag2,
|
||||
char *tag3 ));
|
||||
static LDAPMessage *ldap_msg_merge LDAP_P(( LDAP *ld, LDAPMessage *a, LDAPMessage *b ));
|
||||
static LDAPMessage *ldap_ufn_expand LDAP_P(( LDAP *ld, cancelptype cancelproc,
|
||||
void *cancelparm, char **dns, char *filter, int scope,
|
||||
char **attrs, int aonly, int *err ));
|
||||
|
||||
/*
|
||||
* ldap_ufn_search_ctx - do user friendly searching; provide cancel feature;
|
||||
* specify ldapfilter.conf tags for each phase of search
|
||||
*
|
||||
* ld LDAP descriptor
|
||||
* ufncomp the exploded user friendly name to look for
|
||||
* ncomp number of elements in ufncomp
|
||||
* prefix where to start searching
|
||||
* attrs list of attribute types to return for matches
|
||||
* attrsonly 1 => attributes only 0 => attributes and values
|
||||
* res will contain the result of the search
|
||||
* cancelproc routine that returns non-zero if operation should be
|
||||
* cancelled. This can be a null function pointer. If
|
||||
* it is not 0, the routine will be called periodically.
|
||||
* cancelparm void * that is passed to cancelproc
|
||||
* tag[123] the ldapfilter.conf tag that will be used in phases
|
||||
* 1, 2, and 3 of the search, respectively
|
||||
*
|
||||
* Example:
|
||||
* char *attrs[] = { "mail", "title", 0 };
|
||||
* char *ufncomp[] = { "howes", "umich", "us", 0 }
|
||||
* LDAPMessage *res;
|
||||
* error = ldap_ufn_search_ctx( ld, ufncomp, 3, NULL, attrs, attrsonly,
|
||||
* &res, acancelproc, along, "ufn first",
|
||||
* "ufn intermediate", "ufn last" );
|
||||
*/
|
||||
|
||||
static int
|
||||
ldap_ufn_search_ctx( LDAP *ld, char **ufncomp, int ncomp, char *prefix,
|
||||
char **attrs, int attrsonly, LDAPMessage **res, cancelptype cancelproc,
|
||||
void *cancelparm, char *tag1, char *tag2, char *tag3 )
|
||||
{
|
||||
char *dn, *ftag = NULL;
|
||||
char **dns = NULL;
|
||||
int max, i, err, scope = 0, phase, tries;
|
||||
LDAPFiltInfo *fi;
|
||||
LDAPMessage *tmpcand;
|
||||
LDAPMessage *candidates;
|
||||
static char *objattrs[] = { "objectClass", NULL };
|
||||
|
||||
/*
|
||||
* look up ufn components from most to least significant.
|
||||
* there are 3 phases.
|
||||
* phase 1 search the root for orgs or countries
|
||||
* phase 2 search for orgs
|
||||
* phase 3 search for a person
|
||||
* in phases 1 and 2, we are building a list of candidate DNs,
|
||||
* below which we will search for the final component of the ufn.
|
||||
* for each component we try the filters listed in the
|
||||
* filterconfig file, first one-level (except the last compoment),
|
||||
* then subtree. if any of them produce any results, we go on to
|
||||
* the next component.
|
||||
*/
|
||||
|
||||
*res = NULL;
|
||||
candidates = NULL;
|
||||
phase = 1;
|
||||
for ( ncomp--; ncomp != -1; ncomp-- ) {
|
||||
if ( *ufncomp[ncomp] == '"' ) {
|
||||
char *quote;
|
||||
|
||||
if ( (quote = strrchr( ufncomp[ncomp], '"' )) != NULL )
|
||||
*quote = '\0';
|
||||
AC_MEMCPY( ufncomp[ncomp], ufncomp[ncomp] + 1,
|
||||
strlen( ufncomp[ncomp] + 1 ) + 1 );
|
||||
}
|
||||
if ( ncomp == 0 )
|
||||
phase = 3;
|
||||
|
||||
switch ( phase ) {
|
||||
case 1:
|
||||
ftag = tag1;
|
||||
scope = LDAP_SCOPE_ONELEVEL;
|
||||
break;
|
||||
case 2:
|
||||
ftag = tag2;
|
||||
scope = LDAP_SCOPE_ONELEVEL;
|
||||
break;
|
||||
case 3:
|
||||
ftag = tag3;
|
||||
scope = LDAP_SCOPE_SUBTREE;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* construct an array of DN's to search below from the
|
||||
* list of candidates.
|
||||
*/
|
||||
|
||||
if ( candidates == NULL ) {
|
||||
if ( prefix != NULL ) {
|
||||
if ( (dns = (char **) LDAP_MALLOC( sizeof(char *)
|
||||
* 2 )) == NULL ) {
|
||||
return( ld->ld_errno = LDAP_NO_MEMORY );
|
||||
}
|
||||
dns[0] = LDAP_STRDUP( prefix );
|
||||
dns[1] = NULL;
|
||||
} else {
|
||||
dns = NULL;
|
||||
}
|
||||
} else {
|
||||
i = 0, max = 0;
|
||||
for ( tmpcand = candidates; tmpcand != NULL &&
|
||||
tmpcand->lm_msgtype != LDAP_RES_SEARCH_RESULT;
|
||||
tmpcand = tmpcand->lm_chain )
|
||||
{
|
||||
if ( (dn = ldap_get_dn( ld, tmpcand )) == NULL )
|
||||
continue;
|
||||
|
||||
if ( dns == NULL ) {
|
||||
if ( (dns = (char **) LDAP_MALLOC(
|
||||
sizeof(char *) * 8 )) == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
max = 8;
|
||||
} else if ( i >= max ) {
|
||||
if ( (dns = (char **) LDAP_REALLOC( dns,
|
||||
sizeof(char *) * 2 * max ))
|
||||
== NULL )
|
||||
{
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return( LDAP_NO_MEMORY );
|
||||
}
|
||||
max *= 2;
|
||||
}
|
||||
dns[i++] = dn;
|
||||
dns[i] = NULL;
|
||||
}
|
||||
ldap_msgfree( candidates );
|
||||
candidates = NULL;
|
||||
}
|
||||
tries = 0;
|
||||
tryagain:
|
||||
tries++;
|
||||
for ( fi = ldap_getfirstfilter( ld->ld_filtd, ftag,
|
||||
ufncomp[ncomp] ); fi != NULL;
|
||||
fi = ldap_getnextfilter( ld->ld_filtd ) )
|
||||
{
|
||||
if ( (candidates = ldap_ufn_expand( ld, cancelproc,
|
||||
cancelparm, dns, fi->lfi_filter, scope,
|
||||
phase == 3 ? attrs : objattrs,
|
||||
phase == 3 ? attrsonly : 1, &err )) != NULL )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( err == -1 || err == LDAP_USER_CANCELLED ) {
|
||||
if ( dns != NULL ) {
|
||||
LDAP_VFREE( dns );
|
||||
dns = NULL;
|
||||
}
|
||||
return( err );
|
||||
}
|
||||
}
|
||||
|
||||
if ( candidates == NULL ) {
|
||||
if ( tries < 2 && phase != 3 ) {
|
||||
scope = LDAP_SCOPE_SUBTREE;
|
||||
goto tryagain;
|
||||
} else {
|
||||
if ( dns != NULL ) {
|
||||
LDAP_VFREE( dns );
|
||||
dns = NULL;
|
||||
}
|
||||
return( err );
|
||||
}
|
||||
}
|
||||
|
||||
/* go on to the next component */
|
||||
if ( phase == 1 )
|
||||
phase++;
|
||||
if ( dns != NULL ) {
|
||||
LDAP_VFREE( dns );
|
||||
dns = NULL;
|
||||
}
|
||||
}
|
||||
*res = candidates;
|
||||
|
||||
return( err );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_ufn_search_ct(
|
||||
LDAP *ld, LDAP_CONST char *ufn, char **attrs, int attrsonly,
|
||||
LDAPMessage **res, cancelptype cancelproc, void *cancelparm,
|
||||
char *tag1, char *tag2, char *tag3 )
|
||||
{
|
||||
char **ufncomp, **prefixcomp;
|
||||
char *pbuf;
|
||||
int ncomp, pcomp, i, err = 0;
|
||||
|
||||
/* initialize the getfilter stuff if it's not already */
|
||||
if ( ld->ld_filtd == NULL && ldap_ufn_setfilter( ld, FILTERFILE )
|
||||
== NULL ) {
|
||||
return( ld->ld_errno = LDAP_LOCAL_ERROR );
|
||||
}
|
||||
|
||||
/* call ldap_explode_dn() to break the ufn into its components */
|
||||
if ( (ufncomp = ldap_explode_dn( ufn, 0 )) == NULL )
|
||||
return( ld->ld_errno = LDAP_LOCAL_ERROR );
|
||||
for ( ncomp = 0; ufncomp[ncomp] != NULL; ncomp++ )
|
||||
; /* NULL */
|
||||
|
||||
/* more than two components => try it fully qualified first */
|
||||
if ( ncomp > 2 || ld->ld_ufnprefix == NULL ) {
|
||||
err = ldap_ufn_search_ctx( ld, ufncomp, ncomp, NULL, attrs,
|
||||
attrsonly, res, cancelproc, cancelparm, tag1, tag2, tag3 );
|
||||
|
||||
if ( ldap_count_entries( ld, *res ) > 0 ) {
|
||||
LDAP_VFREE( ufncomp );
|
||||
return( err );
|
||||
} else {
|
||||
ldap_msgfree( *res );
|
||||
*res = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ld->ld_ufnprefix == NULL ) {
|
||||
LDAP_VFREE( ufncomp );
|
||||
return( err );
|
||||
}
|
||||
|
||||
/* if that failed, or < 2 components, use the prefix */
|
||||
if ( (prefixcomp = ldap_explode_dn( ld->ld_ufnprefix, 0 )) == NULL ) {
|
||||
LDAP_VFREE( ufncomp );
|
||||
return( ld->ld_errno = LDAP_LOCAL_ERROR );
|
||||
}
|
||||
for ( pcomp = 0; prefixcomp[pcomp] != NULL; pcomp++ )
|
||||
; /* NULL */
|
||||
if ( (pbuf = (char *) LDAP_MALLOC( strlen( ld->ld_ufnprefix ) + 1 ))
|
||||
== NULL ) {
|
||||
LDAP_VFREE( ufncomp );
|
||||
LDAP_VFREE( prefixcomp );
|
||||
return( ld->ld_errno = LDAP_NO_MEMORY );
|
||||
}
|
||||
|
||||
for ( i = 0; i < pcomp; i++ ) {
|
||||
int j;
|
||||
|
||||
*pbuf = '\0';
|
||||
for ( j = i; j < pcomp; j++ ) {
|
||||
strcat( pbuf, prefixcomp[j] );
|
||||
if ( j + 1 < pcomp )
|
||||
strcat( pbuf, "," );
|
||||
}
|
||||
err = ldap_ufn_search_ctx( ld, ufncomp, ncomp, pbuf, attrs,
|
||||
attrsonly, res, cancelproc, cancelparm, tag1, tag2, tag3 );
|
||||
|
||||
if ( ldap_count_entries( ld, *res ) > 0 ) {
|
||||
break;
|
||||
} else {
|
||||
ldap_msgfree( *res );
|
||||
*res = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LDAP_VFREE( ufncomp );
|
||||
LDAP_VFREE( prefixcomp );
|
||||
LDAP_FREE( pbuf );
|
||||
|
||||
return( err );
|
||||
}
|
||||
|
||||
/*
|
||||
* same as ldap_ufn_search_ct, except without the ability to specify
|
||||
* ldapfilter.conf tags.
|
||||
*/
|
||||
int
|
||||
ldap_ufn_search_c(
|
||||
LDAP *ld, LDAP_CONST char *ufn, char **attrs, int attrsonly,
|
||||
LDAPMessage **res, cancelptype cancelproc, void *cancelparm )
|
||||
{
|
||||
return( ldap_ufn_search_ct( ld, ufn, attrs, attrsonly, res, cancelproc,
|
||||
cancelparm, "ufn first", "ufn intermediate", "ufn last" ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* same as ldap_ufn_search_c without the cancel function
|
||||
*/
|
||||
int
|
||||
ldap_ufn_search_s(
|
||||
LDAP *ld, LDAP_CONST char *ufn, char **attrs, int attrsonly,
|
||||
LDAPMessage **res )
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = ld->ld_timelimit;
|
||||
|
||||
return( ldap_ufn_search_ct( ld, ufn, attrs, attrsonly, res,
|
||||
ld->ld_timelimit ? ldap_ufn_timeout : NULL,
|
||||
ld->ld_timelimit ? (void *) &tv : NULL,
|
||||
"ufn first", "ufn intermediate", "ufn last" ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ldap_msg_merge - merge two ldap search result chains. the more
|
||||
* serious of the two error result codes is kept.
|
||||
*/
|
||||
|
||||
static LDAPMessage *
|
||||
ldap_msg_merge( LDAP *ld, LDAPMessage *a, LDAPMessage *b )
|
||||
{
|
||||
LDAPMessage *end, *aprev, *aend, *bprev, *bend;
|
||||
|
||||
if ( a == NULL )
|
||||
return( b );
|
||||
|
||||
if ( b == NULL )
|
||||
return( a );
|
||||
|
||||
/* find the ends of the a and b chains */
|
||||
aprev = NULL;
|
||||
for ( aend = a; aend->lm_chain != NULL; aend = aend->lm_chain )
|
||||
aprev = aend;
|
||||
bprev = NULL;
|
||||
for ( bend = b; bend->lm_chain != NULL; bend = bend->lm_chain )
|
||||
bprev = bend;
|
||||
|
||||
/* keep result a */
|
||||
if ( ldap_result2error( ld, aend, 0 ) != LDAP_SUCCESS ) {
|
||||
/* remove result b */
|
||||
ldap_msgfree( bend );
|
||||
if ( bprev != NULL )
|
||||
bprev->lm_chain = NULL;
|
||||
else
|
||||
b = NULL;
|
||||
end = aend;
|
||||
if ( aprev != NULL )
|
||||
aprev->lm_chain = NULL;
|
||||
else
|
||||
a = NULL;
|
||||
/* keep result b */
|
||||
} else {
|
||||
/* remove result a */
|
||||
ldap_msgfree( aend );
|
||||
if ( aprev != NULL )
|
||||
aprev->lm_chain = NULL;
|
||||
else
|
||||
a = NULL;
|
||||
end = bend;
|
||||
if ( bprev != NULL )
|
||||
bprev->lm_chain = NULL;
|
||||
else
|
||||
b = NULL;
|
||||
}
|
||||
|
||||
if ( (a == NULL && b == NULL) || (a == NULL && bprev == NULL) ||
|
||||
(b == NULL && aprev == NULL) )
|
||||
return( end );
|
||||
|
||||
if ( a == NULL ) {
|
||||
bprev->lm_chain = end;
|
||||
return( b );
|
||||
} else if ( b == NULL ) {
|
||||
aprev->lm_chain = end;
|
||||
return( a );
|
||||
} else {
|
||||
bprev->lm_chain = end;
|
||||
aprev->lm_chain = b;
|
||||
return( a );
|
||||
}
|
||||
}
|
||||
|
||||
static LDAPMessage *
|
||||
ldap_ufn_expand( LDAP *ld, cancelptype cancelproc, void *cancelparm,
|
||||
char **dns, char *filter, int scope, char **attrs, int aonly,
|
||||
int *err )
|
||||
{
|
||||
LDAPMessage *tmpcand, *tmpres;
|
||||
char *dn;
|
||||
int i, msgid;
|
||||
struct timeval tv;
|
||||
|
||||
/* search for this component below the current candidates */
|
||||
tmpcand = NULL;
|
||||
i = 0;
|
||||
do {
|
||||
if ( dns != NULL )
|
||||
dn = dns[i];
|
||||
else
|
||||
dn = "";
|
||||
|
||||
if (( msgid = ldap_search( ld, dn, scope, filter, attrs,
|
||||
aonly )) == -1 ) {
|
||||
ldap_msgfree( tmpcand );
|
||||
*err = ld->ld_errno;
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000; /* 1/10 of a second */
|
||||
|
||||
do {
|
||||
*err = ldap_result( ld, msgid, 1, &tv, &tmpres );
|
||||
if ( *err == 0 && cancelproc != 0 &&
|
||||
(*cancelproc)( cancelparm ) != 0 ) {
|
||||
ldap_abandon( ld, msgid );
|
||||
*err = LDAP_USER_CANCELLED;
|
||||
ld->ld_errno = LDAP_USER_CANCELLED;
|
||||
}
|
||||
} while ( *err == 0 );
|
||||
|
||||
if ( *err == LDAP_USER_CANCELLED || *err < 0 ||
|
||||
( *err = ldap_result2error( ld, tmpres, 0 )) == -1 ) {
|
||||
ldap_msgfree( tmpcand );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
tmpcand = ldap_msg_merge( ld, tmpcand, tmpres );
|
||||
|
||||
i++;
|
||||
} while ( dns != NULL && dns[i] != NULL );
|
||||
|
||||
if ( ldap_count_entries( ld, tmpcand ) > 0 ) {
|
||||
return( tmpcand );
|
||||
} else {
|
||||
ldap_msgfree( tmpcand );
|
||||
return( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ldap_ufn_setfilter - set the filter config file used in ufn searching
|
||||
*/
|
||||
|
||||
LDAPFiltDesc *
|
||||
ldap_ufn_setfilter( LDAP *ld, LDAP_CONST char *fname )
|
||||
{
|
||||
if ( ld->ld_filtd != NULL )
|
||||
ldap_getfilter_free( ld->ld_filtd );
|
||||
|
||||
return( ld->ld_filtd = ldap_init_getfilter( fname ) );
|
||||
}
|
||||
|
||||
void
|
||||
ldap_ufn_setprefix( LDAP *ld, LDAP_CONST char *prefix )
|
||||
{
|
||||
if ( ld->ld_ufnprefix != NULL )
|
||||
LDAP_FREE( ld->ld_ufnprefix );
|
||||
|
||||
ld->ld_ufnprefix = prefix == NULL
|
||||
? NULL : LDAP_STRDUP( prefix );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_ufn_timeout( void *tvparam )
|
||||
{
|
||||
struct timeval *tv;
|
||||
|
||||
tv = (struct timeval *)tvparam;
|
||||
|
||||
if ( tv->tv_sec != 0 ) {
|
||||
tv->tv_usec = tv->tv_sec * 1000000; /* sec => micro sec */
|
||||
tv->tv_sec = 0;
|
||||
}
|
||||
tv->tv_usec -= 100000; /* 1/10 of a second */
|
||||
|
||||
return( tv->tv_usec <= 0 ? 1 : 0 );
|
||||
}
|
||||
|
|
@ -34,6 +34,12 @@ ldap_unbind_ext(
|
|||
LDAPControl **sctrls,
|
||||
LDAPControl **cctrls )
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* check client controls */
|
||||
rc = ldap_int_client_controls( ld, cctrls );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
|
||||
return ldap_ld_free( ld, 1, sctrls, cctrls );
|
||||
}
|
||||
|
||||
|
|
@ -99,21 +105,6 @@ ldap_ld_free(
|
|||
ld->ld_matched = NULL;
|
||||
}
|
||||
|
||||
if ( ld->ld_host != NULL ) {
|
||||
LDAP_FREE( ld->ld_host );
|
||||
ld->ld_host = NULL;
|
||||
}
|
||||
|
||||
if ( ld->ld_ufnprefix != NULL ) {
|
||||
LDAP_FREE( ld->ld_ufnprefix );
|
||||
ld->ld_ufnprefix = NULL;
|
||||
}
|
||||
|
||||
if ( ld->ld_filtd != NULL ) {
|
||||
ldap_getfilter_free( ld->ld_filtd );
|
||||
ld->ld_filtd = NULL;
|
||||
}
|
||||
|
||||
if ( ld->ld_abandoned != NULL ) {
|
||||
LDAP_FREE( ld->ld_abandoned );
|
||||
ld->ld_abandoned = NULL;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ PROGRAMS = apitest ltest ttest
|
|||
XXDIR = $(srcdir)/../libldap
|
||||
XXSRCS = apitest.c test.c tmpltest.c extended.c \
|
||||
bind.c controls.c open.c result.c error.c compare.c search.c \
|
||||
modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c cyrus.c \
|
||||
modify.c add.c modrdn.c delete.c abandon.c cache.c cyrus.c \
|
||||
getfilter.c sasl.c sbind.c kbind.c unbind.c friendly.c \
|
||||
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
|
||||
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
||||
|
|
@ -28,7 +28,7 @@ OBJS = threads.lo rdwr.lo tpool.lo \
|
|||
thr_pth.lo thr_stub.lo \
|
||||
extended.lo \
|
||||
bind.lo controls.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo cyrus.lo \
|
||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo cache.lo cyrus.lo \
|
||||
getfilter.lo sasl.lo sbind.lo kbind.lo unbind.lo friendly.lo \
|
||||
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
|
||||
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
|
||||
|
|
|
|||
|
|
@ -38,6 +38,33 @@ charray_add(
|
|||
(*a)[n] = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
charray_add_n(
|
||||
char ***a,
|
||||
const char *s,
|
||||
int l
|
||||
)
|
||||
{
|
||||
int n;
|
||||
|
||||
if ( *a == NULL ) {
|
||||
*a = (char **) ch_malloc( 2 * sizeof(char *) );
|
||||
n = 0;
|
||||
} else {
|
||||
for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
|
||||
; /* NULL */
|
||||
}
|
||||
|
||||
*a = (char **) ch_realloc( (char *) *a,
|
||||
(n + 2) * sizeof(char *) );
|
||||
}
|
||||
|
||||
(*a)[n] = (char *) ch_malloc( ( l + 1 ) * sizeof( char ) );
|
||||
strncpy( (*a)[n], s, l );
|
||||
(*a)[n][l] = '\0';
|
||||
(*a)[++n] = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
charray_merge(
|
||||
char ***a,
|
||||
|
|
@ -151,3 +178,38 @@ str2charray( const char *str_in, const char *brkstr )
|
|||
free( str );
|
||||
return( res );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
charray_strcmp( const char **a1, const char **a2 )
|
||||
{
|
||||
for ( ; a1[0] && a2[0]; a1++, a2++ ) {
|
||||
if ( strcmp( a1[0], a2[0] ) ) {
|
||||
return( !0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! ( a1[0] && a2[0] ) ) {
|
||||
return( !0 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
charray_strcasecmp( const char **a1, const char **a2 )
|
||||
{
|
||||
for ( ; a1[0] && a2[0]; a1++, a2++ ) {
|
||||
if ( strcasecmp( a1[0], a2[0] ) ) {
|
||||
return( !0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! ( a1[0] && a2[0] ) ) {
|
||||
return( !0 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ do_compare(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if( ndn == '\0' ) {
|
||||
if( *ndn == '\0' ) {
|
||||
Debug( LDAP_DEBUG_ANY, "do_compare: root dse!\n", 0, 0, 0 );
|
||||
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
|
||||
NULL, "compare upon the root DSE not supported", NULL, NULL );
|
||||
|
|
|
|||
|
|
@ -969,7 +969,7 @@ int connection_read(ber_socket_t s)
|
|||
c->c_needs_tls_accept = 0;
|
||||
|
||||
/* we need to let SASL know */
|
||||
ssl = (void *)ldap_pvt_tls_sb_handle( c->c_sb );
|
||||
ssl = (void *)ldap_pvt_tls_sb_ctx( c->c_sb );
|
||||
|
||||
c->c_tls_ssf = (slap_ssf_t) ldap_pvt_tls_get_strength( ssl );
|
||||
if( c->c_tls_ssf > c->c_ssf ) {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ do_delete(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if( ndn == '\0' ) {
|
||||
if( *ndn == '\0' ) {
|
||||
Debug( LDAP_DEBUG_ANY, "do_delete: root dse!\n", 0, 0, 0 );
|
||||
/* protocolError would likely be a more appropriate error */
|
||||
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ do_modify(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if( ndn == '\0' ) {
|
||||
if( *ndn == '\0' ) {
|
||||
Debug( LDAP_DEBUG_ANY, "do_modify: root dse!\n", 0, 0, 0 );
|
||||
|
||||
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ do_modrdn(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if( ndn == '\0' ) {
|
||||
if( *ndn == '\0' ) {
|
||||
Debug( LDAP_DEBUG_ANY, "do_modrdn: root dse!\n", 0, 0, 0 );
|
||||
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
|
||||
NULL, "cannot rename the root DSE", NULL, NULL );
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ starttls_extop (
|
|||
}
|
||||
|
||||
/* fail if TLS could not be initialized */
|
||||
if (ldap_pvt_tls_get_option(NULL, LDAP_OPT_X_TLS_CERT, &ctx) != 0
|
||||
if (ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &ctx ) != 0
|
||||
|| ctx == NULL)
|
||||
{
|
||||
if (default_referral != NULL) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue