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.
}
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,
break;
}
}
- }
if ( matches == 1 ) {
e = ldap_first_entry( ld, result );
{
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;
#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",
ldap_msgfree( result );
result = NULL;
}
-#ifdef FINGER_UFN
- }
-#endif
if ( rc == LDAP_SIZELIMIT_EXCEEDED ) {
printf( "(Partial results - a size limit was exceeded)\r\n" );
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; ) {
}
} 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
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 );
break;
}
ldap_getfilter_free( filtd );
-#ifdef GO500_UFN
- }
-#endif
if ( matches <= 0 ) {
return;
*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 );
deref = LDAP_DEREF_ALWAYS;
ldap_set_option(ld, LDAP_OPT_DEREF, &deref);
ldap_getfilter_free( filtd );
-#ifdef GO500GW_UFN
- }
-#endif
if ( count == 0 ) {
return;
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;
#endif
NULL };
- ufn = 0;
-
if ( msgp->msg_arg == NULL ) {
return( help_cmd( msgp, 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 )) {
ldap_msgfree( ldmsgp );
}
}
-#ifdef RCPT500_UFN
- }
-#endif /* RCPT500_UFN */
if ( matches == 0 ) {
sprintf( buf, "No matches were found for '%s'\n", msgp->msg_arg );
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 );
} 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 );
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.
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
+++ /dev/null
-
-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
-\f
- 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.
-\f
- 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.
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
*/
#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 ));
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)
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 \
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 \
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 );
}
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;
}
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;
LDAPControl **cctrls,
int *msgidp )
{
+ int rc;
BerElement *ber;
Debug( LDAP_DEBUG_TRACE, "ldap_compare\n", 0, 0, 0 );
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 );
*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;
+}
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;
LDAPControl **cctrls,
int *msgidp )
{
+ int rc;
BerElement *ber;
Debug( LDAP_DEBUG_TRACE, "ldap_delete\n", 0, 0, 0 );
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;
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;
-
-#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 );
+ for ( i = 0; vals[i]; i++ ) {
+ char **rvals;
- 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;
}
+
+ LDAP_FREE( vals[i] );
+ vals[i] = ldap_charray2str( rvals, " + " );
+ LDAP_VFREE( rvals );
}
- *r = '\0';
- return( ufn );
+ ufn = ldap_charray2str( vals, ", " );
+
+ LDAP_VFREE( vals );
+ return ufn;
}
char **
return dn;
}
+#define INQUOTE 1
+#define OUTQUOTE 2
+
static char **
explode_name( const char *name, int notypes, int is_type )
{
#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
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},
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
* (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
SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
#endif
-#ifdef HAVE_TLS
- gopts->ldo_tls_ctx = NULL;
-#endif
-
gopts->ldo_valid = LDAP_INITIALIZED;
-
return;
}
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;
/* 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 */
#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;
#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 */
LDAPControl *const *ctrls,
BerElement *ber ));
+LDAP_F (int) ldap_int_client_controls LDAP_P((
+ LDAP *ld,
+ LDAPControl **ctrlp ));
/*
* in dsparse.c
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 );
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 **,
/*
* 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
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 );
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 );
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 );
}
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;
}
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) {
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;
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
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 )
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 )
{
LDAP_FREE( ha_buf );
return host;
}
-#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND || HAVE_TLS */
+#endif
/* for UNIX */
}
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 );
}
{
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;
int sizelimit,
int *msgidp )
{
+ int rc;
BerElement *ber;
int timelimit;
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
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)? " );
* 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
}
void *
-ldap_pvt_tls_sb_handle( Sockbuf *sb )
+ldap_pvt_tls_sb_ctx( Sockbuf *sb )
{
void *p;
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 )
{
}
-const char *
+char *
ldap_pvt_tls_get_peer( void *s )
{
X509 *x;
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);
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;
}
}
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;
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 )
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;
}
}
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 ?
}
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 ) {
}
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;
}
}
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();
/*
* 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 */
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
*/
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;
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;
}
+++ /dev/null
-/* $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 );
-}
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 );
}
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;
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 \
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 \
(*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,
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;
+}
+
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 );
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 ) {
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,
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,
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 );
}
/* 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) {