summaryrefslogtreecommitdiffstats
path: root/ldap/servers
diff options
context:
space:
mode:
authorRich Megginson <rmeggins@redhat.com>2009-07-06 12:11:01 -0600
committerRich Megginson <rmeggins@redhat.com>2009-07-07 08:32:42 -0600
commit209521323f731daad54682fd98715f7b22c88c78 (patch)
tree74a1fa8df06641fe543c8518e4db4357ab610828 /ldap/servers
parent3116dbec570b65d2d0a1df5bd000f6e63439e8ee (diff)
downloadds-209521323f731daad54682fd98715f7b22c88c78.tar.gz
ds-209521323f731daad54682fd98715f7b22c88c78.tar.xz
ds-209521323f731daad54682fd98715f7b22c88c78.zip
OpenLDAP supportcleanup
These changes allow the server to be built with OpenLDAP (2.4.17+). A brief summary of the changes: * #defines not provided by OpenLDAP were copied into slapi-plugin.h and protected with #ifndef blocks * where it made sense, I created slapi wrapper functions for things like URL and LDIF processing to abstract way the differences in the APIs * I created a new file utf8.c which contains the UTF8 functions from MozLDAP - this is only compiled when using OpenLDAP * I tried to clean up the code - use the _ext versions of LDAP functions everywhere since the older versions should be considered deprecated * I removed some unused code NOTE that this should still be considered a work in progress since it depends on functionality not yet present in a released version of OpenLDAP, for NSS crypto and for the LDIF public API.
Diffstat (limited to 'ldap/servers')
-rw-r--r--ldap/servers/plugins/acl/acl.c4
-rw-r--r--ldap/servers/plugins/acl/aclutil.c4
-rw-r--r--ldap/servers/plugins/chainingdb/cb.h1
-rw-r--r--ldap/servers/plugins/chainingdb/cb_bind.c4
-rw-r--r--ldap/servers/plugins/chainingdb/cb_instance.c9
-rw-r--r--ldap/servers/plugins/chainingdb/cb_search.c10
-rw-r--r--ldap/servers/plugins/chainingdb/cb_utils.c31
-rw-r--r--ldap/servers/plugins/dna/dna.c16
-rw-r--r--ldap/servers/plugins/passthru/passthru.h1
-rw-r--r--ldap/servers/plugins/passthru/ptbind.c4
-rw-r--r--ldap/servers/plugins/passthru/ptconfig.c10
-rw-r--r--ldap/servers/plugins/passthru/ptutil.c30
-rw-r--r--ldap/servers/plugins/pwdstorage/clear_pwd.c4
-rw-r--r--ldap/servers/plugins/pwdstorage/crypt_pwd.c4
-rw-r--r--ldap/servers/plugins/pwdstorage/md5_pwd.c4
-rw-r--r--ldap/servers/plugins/pwdstorage/ns-mta-md5_pwd.c4
-rw-r--r--ldap/servers/plugins/pwdstorage/pwdstorage.h49
-rw-r--r--ldap/servers/plugins/pwdstorage/sha_pwd.c56
-rw-r--r--ldap/servers/plugins/pwdstorage/ssha_pwd.c23
-rw-r--r--ldap/servers/plugins/replication/cl5_api.c86
-rw-r--r--ldap/servers/plugins/replication/repl5_connection.c97
-rw-r--r--ldap/servers/plugins/replication/repl5_replica.c6
-rw-r--r--ldap/servers/plugins/replication/repl5_total.c2
-rw-r--r--ldap/servers/plugins/replication/replutil.c10
-rw-r--r--ldap/servers/plugins/replication/urp_glue.c2
-rw-r--r--ldap/servers/plugins/replication/windows_connection.c37
-rw-r--r--ldap/servers/plugins/retrocl/retrocl_po.c4
-rw-r--r--ldap/servers/slapd/add.c5
-rw-r--r--ldap/servers/slapd/auditlog.c4
-rw-r--r--ldap/servers/slapd/auth.c4
-rw-r--r--ldap/servers/slapd/back-ldbm/ancestorid.c4
-rw-r--r--ldap/servers/slapd/back-ldbm/import-threads.c4
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_attr.c8
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_config.c2
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_index_config.c10
-rw-r--r--ldap/servers/slapd/back-ldbm/ldbm_modrdn.c18
-rw-r--r--ldap/servers/slapd/back-ldbm/sort.c9
-rw-r--r--ldap/servers/slapd/back-ldbm/vlv_srch.c24
-rw-r--r--ldap/servers/slapd/back-ldbm/vlv_srch.h11
-rw-r--r--ldap/servers/slapd/charray.c6
-rw-r--r--ldap/servers/slapd/connection.c64
-rw-r--r--ldap/servers/slapd/conntable.c9
-rw-r--r--ldap/servers/slapd/control.c7
-rw-r--r--ldap/servers/slapd/daemon.c169
-rw-r--r--ldap/servers/slapd/dse.c4
-rw-r--r--ldap/servers/slapd/entry.c78
-rw-r--r--ldap/servers/slapd/fe.h2
-rw-r--r--ldap/servers/slapd/fedse.c4
-rw-r--r--ldap/servers/slapd/filter.c21
-rw-r--r--ldap/servers/slapd/filterentry.c4
-rw-r--r--ldap/servers/slapd/getfilelist.c2
-rw-r--r--ldap/servers/slapd/globals.c1
-rw-r--r--ldap/servers/slapd/ldaputil.c1529
-rw-r--r--ldap/servers/slapd/libglobs.c1
-rw-r--r--ldap/servers/slapd/modify.c4
-rw-r--r--ldap/servers/slapd/modrdn.c4
-rw-r--r--ldap/servers/slapd/modutil.c2
-rw-r--r--ldap/servers/slapd/operation.c37
-rw-r--r--ldap/servers/slapd/passwd_extop.c16
-rw-r--r--ldap/servers/slapd/proto-slap.h3
-rw-r--r--ldap/servers/slapd/rdn.c6
-rw-r--r--ldap/servers/slapd/referral.c17
-rw-r--r--ldap/servers/slapd/saslbind.c4
-rw-r--r--ldap/servers/slapd/schema.c2
-rw-r--r--ldap/servers/slapd/slap.h7
-rw-r--r--ldap/servers/slapd/slapi-plugin.h219
-rw-r--r--ldap/servers/slapd/slapi-private.h2
-rw-r--r--ldap/servers/slapd/ssl.c21
-rw-r--r--ldap/servers/slapd/time.c4
-rw-r--r--ldap/servers/slapd/tools/ldaptool.h7
-rw-r--r--ldap/servers/slapd/tools/ldclt/ldapfct.c177
-rw-r--r--ldap/servers/slapd/tools/ldclt/ldclt.c4
-rw-r--r--ldap/servers/slapd/tools/ldclt/ldclt.h34
-rw-r--r--ldap/servers/slapd/tools/ldclt/scalab01.c108
-rw-r--r--ldap/servers/slapd/tools/ldif.c19
-rw-r--r--ldap/servers/slapd/tools/pwenc.c1
-rw-r--r--ldap/servers/slapd/tools/rsearch/addthread.c7
-rw-r--r--ldap/servers/slapd/tools/rsearch/searchthread.c8
-rw-r--r--ldap/servers/slapd/utf8.c310
-rw-r--r--ldap/servers/slapd/util.c1234
-rw-r--r--ldap/servers/snmp/main.c32
81 files changed, 3022 insertions, 1783 deletions
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index f7f58650..b708cada 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -195,9 +195,9 @@ static int check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, char *dn,
}
}
}
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
}
- ldap_value_free( dns );
+ slapi_ldap_value_free( dns );
}
return(retCode);
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index f0c1da5d..599fdbd0 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -585,8 +585,8 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
cleanup:
- ldap_value_free ( a_dns );
- ldap_value_free ( e_dns );
+ slapi_ldap_value_free ( a_dns );
+ slapi_ldap_value_free ( e_dns );
if ( 0 != rc ) /* error */ {
slapi_ch_free ( (void **) &buf );
buf = NULL;
diff --git a/ldap/servers/plugins/chainingdb/cb.h b/ldap/servers/plugins/chainingdb/cb.h
index 209fdd37..a93950d9 100644
--- a/ldap/servers/plugins/chainingdb/cb.h
+++ b/ldap/servers/plugins/chainingdb/cb.h
@@ -485,7 +485,6 @@ int cb_back_cleanup (Slapi_PBlock *pb );
long cb_atol(char *str);
Slapi_Entry * cb_LDAPMessage2Entry(LDAP * ctx, LDAPMessage * msg, int attrsonly);
-char * cb_urlparse_err2string( int err );
char * cb_get_rootdn();
struct berval ** referrals2berval(char ** referrals);
cb_backend_instance * cb_get_instance(Slapi_Backend * be);
diff --git a/ldap/servers/plugins/chainingdb/cb_bind.c b/ldap/servers/plugins/chainingdb/cb_bind.c
index d8c9f87b..638404a6 100644
--- a/ldap/servers/plugins/chainingdb/cb_bind.c
+++ b/ldap/servers/plugins/chainingdb/cb_bind.c
@@ -162,7 +162,7 @@ cb_sasl_bind_once_s( cb_conn_pool *pool, char *dn, int method, char * mechanism,
char * matcheddnp2, * errmsgp2;
matcheddnp2=errmsgp2=NULL;
- rc = ldap_get_lderrno( ld, &matcheddnp2, &errmsgp2 );
+ rc = slapi_ldap_get_lderrno( ld, &matcheddnp2, &errmsgp2 );
/* Need to allocate errmsgs */
if (matcheddnp2)
@@ -185,7 +185,7 @@ cb_sasl_bind_once_s( cb_conn_pool *pool, char *dn, int method, char * mechanism,
&referrals, resctrlsp, 1 );
if ( referrals != NULL ) {
*refurlsp = referrals2berval( referrals );
- ldap_value_free( referrals );
+ slapi_ldap_value_free( referrals );
}
/* realloc matcheddn & errmsg because the mem alloc model */
/* may differ from malloc */
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index f813cec0..1c08bd9f 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -714,15 +714,16 @@ static int cb_instance_hosturl_set(void *arg, void *value, char *errorbuf, int p
char *url = (char *) value;
LDAPURLDesc *ludp=NULL;
int rc=LDAP_SUCCESS;
+ int secure = 0;
- if (( rc = ldap_url_parse( url, &ludp )) != 0 ) {
- PL_strncpyz(errorbuf,cb_urlparse_err2string( rc ), SLAPI_DSE_RETURNTEXT_SIZE);
+ if (( rc = slapi_ldap_url_parse( url, &ludp, 0, &secure )) != 0 ) {
+ PL_strncpyz(errorbuf,slapi_urlparse_err2string( rc ), SLAPI_DSE_RETURNTEXT_SIZE);
if (CB_CONFIG_PHASE_INITIALIZATION == phase)
inst->pool->url=slapi_ch_strdup("");
return(LDAP_INVALID_SYNTAX);
}
- if (ludp && (ludp->lud_options & LDAP_URL_OPT_SECURE) && inst && inst->rwl_config_lock) {
+ if (ludp && secure && inst && inst->rwl_config_lock) {
int isgss = 0;
PR_RWLock_Rlock(inst->rwl_config_lock);
isgss = inst->pool->mech && !PL_strcasecmp(inst->pool->mech, "GSSAPI");
@@ -768,7 +769,7 @@ static int cb_instance_hosturl_set(void *arg, void *value, char *errorbuf, int p
inst->pool->hostname = slapi_ch_strdup( ludp->lud_host );
}
inst->pool->url = slapi_ch_strdup( url);
- inst->pool->secure = (( ludp->lud_options & LDAP_URL_OPT_SECURE ) != 0 );
+ inst->pool->secure = secure;
if ((ludp->lud_port==0) && inst->pool->secure)
inst->pool->port=CB_LDAP_SECURE_PORT;
diff --git a/ldap/servers/plugins/chainingdb/cb_search.c b/ldap/servers/plugins/chainingdb/cb_search.c
index 94b680f7..895d6f2b 100644
--- a/ldap/servers/plugins/chainingdb/cb_search.c
+++ b/ldap/servers/plugins/chainingdb/cb_search.c
@@ -298,7 +298,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
switch ( rc ) {
case -1:
/* An error occurred. return now */
- rc = ldap_get_lderrno(ld,NULL,NULL);
+ rc = slapi_ldap_get_lderrno(ld,NULL,NULL);
/* tuck away some errors in a OPERATION_ERROR */
if (CB_LDAP_CONN_ERROR(rc)) {
cb_send_ldap_result(pb,LDAP_OPERATIONS_ERROR, NULL,
@@ -366,7 +366,7 @@ chainingdb_build_candidate_list ( Slapi_PBlock *pb )
rc=-1;
} else
if ( rc != LDAP_SUCCESS ) {
- ldap_get_lderrno( ctx->ld, &matched_msg, &error_msg );
+ slapi_ldap_get_lderrno( ctx->ld, &matched_msg, &error_msg );
cb_send_ldap_result( pb, rc, matched_msg,
error_msg,0,NULL);
/* BEWARE: matched_msg and error_msg points */
@@ -558,7 +558,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
case -1:
/* An error occurred. */
- rc = ldap_get_lderrno( ctx->ld, NULL, NULL );
+ rc = slapi_ldap_get_lderrno( ctx->ld, NULL, NULL );
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET,NULL);
slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY,NULL);
@@ -670,7 +670,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
}
if (referrals != NULL) {
- ldap_value_free( referrals );
+ slapi_ldap_value_free( referrals );
}
return 0;
@@ -694,7 +694,7 @@ chainingdb_next_search_entry ( Slapi_PBlock *pb )
retcode=-1;
} else
if ( rc != LDAP_SUCCESS ) {
- ldap_get_lderrno( ctx->ld, &matched_msg, &error_msg );
+ slapi_ldap_get_lderrno( ctx->ld, &matched_msg, &error_msg );
cb_send_ldap_result( pb, rc, matched_msg, NULL, 0, NULL);
/* BEWARE: Don't free matched_msg && error_msg */
diff --git a/ldap/servers/plugins/chainingdb/cb_utils.c b/ldap/servers/plugins/chainingdb/cb_utils.c
index 128c2adc..4878e1a8 100644
--- a/ldap/servers/plugins/chainingdb/cb_utils.c
+++ b/ldap/servers/plugins/chainingdb/cb_utils.c
@@ -94,7 +94,7 @@ Slapi_Entry * cb_LDAPMessage2Entry(LDAP * ld, LDAPMessage * msg, int attrsonly)
}
}
if ( NULL != ber )
- ldap_ber_free( ber, 0 );
+ ber_free( ber, 0 );
return e;
}
@@ -120,35 +120,6 @@ struct berval ** referrals2berval(char ** referrals) {
return val;
}
-
-char *
-cb_urlparse_err2string( int err )
-{
- char *s="internal error";
-
- switch( err ) {
- case 0:
- s = "no error";
- break;
- case LDAP_URL_ERR_NOTLDAP:
- s = "missing ldap:// or ldaps://";
- break;
- case LDAP_URL_ERR_NODN:
- s = "missing suffix";
- break;
- case LDAP_URL_ERR_BADSCOPE:
- s = "invalid search scope";
- break;
- case LDAP_URL_ERR_MEM:
- s = "unable to allocate memory";
- break;
- case LDAP_URL_ERR_PARAM:
- s = "bad parameter to an LDAP URL function";
- break;
- }
-
- return( s );
-}
/*
** Return LDAP_SUCCESS if an internal operation needs to be forwarded to
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 0f509c05..b198ef3a 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -53,7 +53,6 @@
#include "dirlite_strings.h"
#include "dirver.h"
#include "prclist.h"
-#include "ldif.h"
/* Required to get portable printf/scanf format macros */
#ifdef HAVE_INTTYPES_H
@@ -1499,7 +1498,10 @@ static int dna_request_range(struct configEntry *config_entry,
int set_extend_flag = 0;
int ret = LDAP_OPERATIONS_ERROR;
int port = 0;
-
+ int timelimit;
+#if defined(USE_OPENLDAP)
+ struct timeval timeout;
+#endif
/* See if we're allowed to send a range request now */
slapi_lock_mutex(config_entry->extend_lock);
if (config_entry->extend_in_progress) {
@@ -1543,9 +1545,15 @@ static int dna_request_range(struct configEntry *config_entry,
/* Disable referrals and set timelimit and a connect timeout */
ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &config_entry->timeout);
+ timelimit = config_entry->timeout / 1000; /* timeout is in msec */
+ ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit);
+#if defined(USE_OPENLDAP)
+ timeout.tv_sec = config_entry->timeout / 1000;
+ timeout.tv_usec = (config_entry->timeout % 1000) * 1000;
+ ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
+#else
ldap_set_option(ld, LDAP_X_OPT_CONNECT_TIMEOUT, &config_entry->timeout);
-
+#endif
/* Bind to the replica server */
ret = slapi_ldap_bind(ld, bind_dn, bind_passwd, bind_method,
NULL, NULL, NULL, NULL);
diff --git a/ldap/servers/plugins/passthru/passthru.h b/ldap/servers/plugins/passthru/passthru.h
index 022a57ae..34f8f696 100644
--- a/ldap/servers/plugins/passthru/passthru.h
+++ b/ldap/servers/plugins/passthru/passthru.h
@@ -163,6 +163,5 @@ void passthru_close_all_connections( PassThruConfig *cfg );
struct berval **passthru_strs2bervals( char **ss );
char ** passthru_bervals2strs( struct berval **bvs );
void passthru_free_bervals( struct berval **bvs );
-char *passthru_urlparse_err2string( int err );
#endif /* _PASSTHRU_H_ */
diff --git a/ldap/servers/plugins/passthru/ptbind.c b/ldap/servers/plugins/passthru/ptbind.c
index 2cce0b57..063ba150 100644
--- a/ldap/servers/plugins/passthru/ptbind.c
+++ b/ldap/servers/plugins/passthru/ptbind.c
@@ -158,7 +158,7 @@ passthru_simple_bind_once_s( PassThruServer *srvr, char *dn,
/*
* Some other error occurred (no result received).
*/
- rc = ldap_get_lderrno( ld, matcheddnp, errmsgp );
+ rc = slapi_ldap_get_lderrno( ld, matcheddnp, errmsgp );
} else {
/*
* Got a result from remote server -- parse it.
@@ -167,7 +167,7 @@ passthru_simple_bind_once_s( PassThruServer *srvr, char *dn,
&referrals, resctrlsp, 1 );
if ( referrals != NULL ) {
*refurlsp = passthru_strs2bervals( referrals );
- ldap_value_free( referrals );
+ slapi_ldap_value_free( referrals );
}
}
diff --git a/ldap/servers/plugins/passthru/ptconfig.c b/ldap/servers/plugins/passthru/ptconfig.c
index b7bb1386..fac0c5bd 100644
--- a/ldap/servers/plugins/passthru/ptconfig.c
+++ b/ldap/servers/plugins/passthru/ptconfig.c
@@ -131,6 +131,7 @@ passthru_config( int argc, char **argv )
*/
prevsrvr = NULL;
for ( i = 0; i < argc; ++i ) {
+ int secure = 0;
char *p = NULL;
srvr = (PassThruServer *)slapi_ch_calloc( 1, sizeof( PassThruServer ));
srvr->ptsrvr_url = slapi_ch_strdup( argv[i] );
@@ -230,10 +231,10 @@ passthru_config( int argc, char **argv )
/*
* parse the LDAP URL
*/
- if (( rc = ldap_url_parse( srvr->ptsrvr_url, &ludp )) != 0 ) {
+ if (( rc = slapi_ldap_url_parse( srvr->ptsrvr_url, &ludp, 0, &secure )) != 0 ) {
slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
"unable to parse LDAP URL \"%s\" (%s)\n",
- srvr->ptsrvr_url, passthru_urlparse_err2string( rc ));
+ srvr->ptsrvr_url, slapi_urlparse_err2string( rc ));
return( LDAP_PARAM_ERROR );
}
@@ -246,8 +247,7 @@ passthru_config( int argc, char **argv )
srvr->ptsrvr_hostname = slapi_ch_strdup( ludp->lud_host );
srvr->ptsrvr_port = ludp->lud_port;
- srvr->ptsrvr_secure =
- (( ludp->lud_options & LDAP_URL_OPT_SECURE ) != 0 );
+ srvr->ptsrvr_secure = secure;
if (starttls) {
srvr->ptsrvr_secure = 2;
}
@@ -265,7 +265,7 @@ passthru_config( int argc, char **argv )
/*
* split the DN into multiple suffixes (separated by ';')
*/
- if (( suffixarray = ldap_str2charray( ludp->lud_dn, ";" )) == NULL ) {
+ if (( suffixarray = slapi_str2charray( ludp->lud_dn, ";" )) == NULL ) {
slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
"unable to parse suffix string \"%s\" within \"%s\"\n",
ludp->lud_dn, srvr->ptsrvr_url );
diff --git a/ldap/servers/plugins/passthru/ptutil.c b/ldap/servers/plugins/passthru/ptutil.c
index 399e5b5a..48f3c405 100644
--- a/ldap/servers/plugins/passthru/ptutil.c
+++ b/ldap/servers/plugins/passthru/ptutil.c
@@ -116,33 +116,3 @@ passthru_free_bervals( struct berval **bvs )
}
slapi_ch_free( (void **)&bvs );
}
-
-
-char *
-passthru_urlparse_err2string( int err )
-{
- char *s;
-
- switch( err ) {
- case 0:
- s = "no error";
- break;
- case LDAP_URL_ERR_NOTLDAP:
- s = "missing ldap:// or ldaps://";
- break;
- case LDAP_URL_ERR_NODN:
- s = "missing suffix";
- break;
- case LDAP_URL_ERR_BADSCOPE:
- s = "invalid search scope";
- break;
- case LDAP_URL_ERR_MEM:
- s = "unable to allocate memory";
- break;
- case LDAP_URL_ERR_PARAM:
- s = "bad parameter to an LDAP URL function";
- break;
- }
-
- return( s );
-}
diff --git a/ldap/servers/plugins/pwdstorage/clear_pwd.c b/ldap/servers/plugins/pwdstorage/clear_pwd.c
index fd8ab46b..19011ac6 100644
--- a/ldap/servers/plugins/pwdstorage/clear_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/clear_pwd.c
@@ -52,13 +52,13 @@
#include "pwdstorage.h"
int
-clear_pw_cmp( char *userpwd, char *dbpwd )
+clear_pw_cmp( const char *userpwd, const char *dbpwd )
{
return( strcmp( userpwd, dbpwd ));
}
char *
-clear_pw_enc( char *pwd )
+clear_pw_enc( const char *pwd )
{
/* Just return NULL if pwd is NULL */
if (!pwd)
diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
index 02ec7d08..666fd4b3 100644
--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c
@@ -79,7 +79,7 @@ crypt_init()
}
int
-crypt_pw_cmp( char *userpwd, char *dbpwd )
+crypt_pw_cmp( const char *userpwd, const char *dbpwd )
{
int rc;
char *cp;
@@ -96,7 +96,7 @@ crypt_pw_cmp( char *userpwd, char *dbpwd )
}
char *
-crypt_pw_enc( char *pwd )
+crypt_pw_enc( const char *pwd )
{
char *cry, salt[3];
char *enc= NULL;
diff --git a/ldap/servers/plugins/pwdstorage/md5_pwd.c b/ldap/servers/plugins/pwdstorage/md5_pwd.c
index b63c5b04..7dec2d47 100644
--- a/ldap/servers/plugins/pwdstorage/md5_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/md5_pwd.c
@@ -57,7 +57,7 @@
#define MD5_SUBSYSTEM_NAME "MD5 password hash"
int
-md5_pw_cmp( char *userpwd, char *dbpwd )
+md5_pw_cmp( const char *userpwd, const char *dbpwd )
{
int rc=-1;
char * bver;
@@ -96,7 +96,7 @@ loser:
}
char *
-md5_pw_enc( char *pwd )
+md5_pw_enc( const char *pwd )
{
char * bver, *enc=NULL;
PK11Context *ctx=NULL;
diff --git a/ldap/servers/plugins/pwdstorage/ns-mta-md5_pwd.c b/ldap/servers/plugins/pwdstorage/ns-mta-md5_pwd.c
index 467766fb..3dc7e34d 100644
--- a/ldap/servers/plugins/pwdstorage/ns-mta-md5_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/ns-mta-md5_pwd.c
@@ -77,7 +77,7 @@ ns_mta_hexify(char *buffer, char *str, int len)
}
static char *
-ns_mta_hash_alg(char *buffer, char *salt, char *passwd)
+ns_mta_hash_alg(char *buffer, char *salt, const char *passwd)
{
mta_MD5_CTX context;
char *saltstr;
@@ -102,7 +102,7 @@ ns_mta_hash_alg(char *buffer, char *salt, char *passwd)
}
int
-ns_mta_md5_pw_cmp(char * clear, char *mangled)
+ns_mta_md5_pw_cmp(const char * clear, const char *mangled)
{
char mta_hash[33];
char mta_salt[33];
diff --git a/ldap/servers/plugins/pwdstorage/pwdstorage.h b/ldap/servers/plugins/pwdstorage/pwdstorage.h
index ccd0deee..975d789e 100644
--- a/ldap/servers/plugins/pwdstorage/pwdstorage.h
+++ b/ldap/servers/plugins/pwdstorage/pwdstorage.h
@@ -46,6 +46,7 @@
#include "slapi-plugin.h"
#include <ssl.h>
#include "nspr.h"
+#include "plbase64.h"
#include "ldif.h"
#include "md5.h"
@@ -54,7 +55,7 @@
#define PWD_HASH_PREFIX_START '{'
#define PWD_HASH_PREFIX_END '}'
-#define MAX_SHA_HASH_SIZE 64
+#define MAX_SHA_HASH_SIZE HASH_LENGTH_MAX
#define SHA1_SCHEME_NAME "SHA"
#define SHA1_NAME_LEN 3
@@ -81,31 +82,31 @@
#define MD5_SCHEME_NAME "MD5"
#define MD5_NAME_LEN 3
-SECStatus sha_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt, unsigned int secOID);
-int sha_pw_cmp( char *userpwd, char *dbpwd, unsigned int shaLen );
-char * sha_pw_enc( char *pwd, unsigned int shaLen );
-char * salted_sha_pw_enc( char *pwd, unsigned int shaLen );
-int sha1_pw_cmp( char *userpwd, char *dbpwd );
-char * sha1_pw_enc( char *pwd );
-char * salted_sha1_pw_enc( char *pwd );
-int sha256_pw_cmp( char *userpwd, char *dbpwd );
-char * sha256_pw_enc( char *pwd );
-char * salted_sha256_pw_enc( char *pwd );
-int sha384_pw_cmp( char *userpwd, char *dbpwd );
-char * sha384_pw_enc( char *pwd );
-char * salted_sha384_pw_enc( char *pwd );
-int sha512_pw_cmp( char *userpwd, char *dbpwd );
-char * sha512_pw_enc( char *pwd );
-char * salted_sha512_pw_enc( char *pwd );
-int clear_pw_cmp( char *userpwd, char *dbpwd );
-char *clear_pw_enc( char *pwd );
+SECStatus sha_salted_hash(char *hash_out, const char *pwd, struct berval *salt, unsigned int secOID);
+int sha_pw_cmp( const char *userpwd, const char *dbpwd, unsigned int shaLen );
+char * sha_pw_enc( const char *pwd, unsigned int shaLen );
+char * salted_sha_pw_enc( const char *pwd, unsigned int shaLen );
+int sha1_pw_cmp( const char *userpwd, const char *dbpwd );
+char * sha1_pw_enc( const char *pwd );
+char * salted_sha1_pw_enc( const char *pwd );
+int sha256_pw_cmp( const char *userpwd, const char *dbpwd );
+char * sha256_pw_enc( const char *pwd );
+char * salted_sha256_pw_enc( const char *pwd );
+int sha384_pw_cmp( const char *userpwd, const char *dbpwd );
+char * sha384_pw_enc( const char *pwd );
+char * salted_sha384_pw_enc( const char *pwd );
+int sha512_pw_cmp( const char *userpwd, const char *dbpwd );
+char * sha512_pw_enc( const char *pwd );
+char * salted_sha512_pw_enc( const char *pwd );
+int clear_pw_cmp( const char *userpwd, const char *dbpwd );
+char *clear_pw_enc( const char *pwd );
#ifndef _WIN32
void crypt_init();
-int crypt_pw_cmp( char *userpwd, char *dbpwd );
-char *crypt_pw_enc( char *pwd );
+int crypt_pw_cmp( const char *userpwd, const char *dbpwd );
+char *crypt_pw_enc( const char *pwd );
#endif
-int ns_mta_md5_pw_cmp( char *userpwd, char *dbpwd );
-int md5_pw_cmp( char *userpwd, char *dbpwd );
-char *md5_pw_enc( char *pwd );
+int ns_mta_md5_pw_cmp( const char *userpwd, const char *dbpwd );
+int md5_pw_cmp( const char *userpwd, const char *dbpwd );
+char *md5_pw_enc( const char *pwd );
#endif /* _PWDSTORAGE_H */
diff --git a/ldap/servers/plugins/pwdstorage/sha_pwd.c b/ldap/servers/plugins/pwdstorage/sha_pwd.c
index ea0afdd0..e54feab7 100644
--- a/ldap/servers/plugins/pwdstorage/sha_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/sha_pwd.c
@@ -67,20 +67,21 @@ static char *plugin_name = "NSPwdStoragePlugin";
*/
int
-sha_pw_cmp (char *userpwd, char *dbpwd, unsigned int shaLen )
+sha_pw_cmp (const char *userpwd, const char *dbpwd, unsigned int shaLen )
{
/*
* SHA passwords are stored in the database as shaLen bytes of
* hash, followed by zero or more bytes of salt, all BASE64 encoded.
*/
int result = 1; /* failure */
- unsigned char userhash[MAX_SHA_HASH_SIZE];
- unsigned char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3];
- unsigned char *dbhash = quick_dbhash;
+ char userhash[MAX_SHA_HASH_SIZE];
+ char quick_dbhash[MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH + 3];
+ char *dbhash = quick_dbhash;
struct berval salt;
int hash_len; /* must be a signed valued -- see below */
unsigned int secOID;
char *schemeName;
+ char *hashresult = NULL;
/* Determine which algorithm we're using */
switch (shaLen) {
@@ -107,24 +108,20 @@ sha_pw_cmp (char *userpwd, char *dbpwd, unsigned int shaLen )
/*
* Decode hash stored in database.
- *
- * Note that ldif_base64_decode() returns a value less than zero to
- * indicate that a decoding error occurred, so it is critical that
- * hash_len be a signed value.
*/
- hash_len = (((strlen(dbpwd) + 3) / 4) * 3); /* maybe less */
+ hash_len = (strlen(dbpwd) * 3) / 4; /* includes the trailing = if any */
if ( hash_len > sizeof(quick_dbhash) ) { /* get more space: */
- dbhash = (unsigned char*) slapi_ch_malloc( hash_len );
+ dbhash = (char*) slapi_ch_malloc( hash_len );
if ( dbhash == NULL ) goto loser;
}
- hash_len = ldif_base64_decode( dbpwd, dbhash );
- if (hash_len < 0) {
+ hashresult = PL_Base64Decode( dbpwd, 0, dbhash );
+ if (NULL == hashresult) {
slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, hasherrmsg, schemeName, dbpwd );
goto loser;
} else if ( hash_len >= shaLen ) {
salt.bv_val = (void*)(dbhash + shaLen);
- salt.bv_len = hash_len - shaLen;
- } else if ( hash_len == DS40B1_SALTED_SHA_LENGTH ) {
+ salt.bv_len = SHA_SALT_LENGTH;
+ } else if ( hash_len >= DS40B1_SALTED_SHA_LENGTH ) {
salt.bv_val = (void*)dbhash;
salt.bv_len = 8;
} else { /* unsupported, invalid BASE64 (hash_len < 0), or similar */
@@ -139,19 +136,19 @@ sha_pw_cmp (char *userpwd, char *dbpwd, unsigned int shaLen )
}
/* the proof is in the comparison... */
- result = ( hash_len == DS40B1_SALTED_SHA_LENGTH ) ?
- ( memcmp( userhash, dbhash + 8, hash_len - 8 )) :
- ( memcmp( userhash, dbhash, shaLen ));
+ result = ( hash_len >= shaLen ) ?
+ ( memcmp( userhash, dbhash, shaLen )) : /* include salt */
+ ( memcmp( userhash, dbhash + 8, hash_len - 8 )); /* exclude salt */
loser:
- if ( dbhash && dbhash != quick_dbhash ) slapi_ch_free( (void**)&dbhash );
+ if ( dbhash && dbhash != quick_dbhash ) slapi_ch_free_string( &dbhash );
return result;
}
char *
-sha_pw_enc( char *pwd, unsigned int shaLen )
+sha_pw_enc( const char *pwd, unsigned int shaLen )
{
- unsigned char hash[MAX_SHA_HASH_SIZE];
+ char hash[MAX_SHA_HASH_SIZE];
char *enc;
char *schemeName;
unsigned int schemeNameLen;
@@ -196,8 +193,7 @@ sha_pw_enc( char *pwd, unsigned int shaLen )
sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
PWD_HASH_PREFIX_END );
- (void)ldif_base64_encode( hash, enc + 2 + schemeNameLen,
- shaLen, -1 );
+ (void)PL_Base64Encode( hash, shaLen, enc + 2 + schemeNameLen );
return( enc );
}
@@ -206,25 +202,25 @@ sha_pw_enc( char *pwd, unsigned int shaLen )
* Wrapper password comparison functions
*/
int
-sha1_pw_cmp (char *userpwd, char *dbpwd )
+sha1_pw_cmp (const char *userpwd, const char *dbpwd )
{
return sha_pw_cmp( userpwd, dbpwd, SHA1_LENGTH );
}
int
-sha256_pw_cmp (char *userpwd, char *dbpwd )
+sha256_pw_cmp (const char *userpwd, const char *dbpwd )
{
return sha_pw_cmp( userpwd, dbpwd, SHA256_LENGTH );
}
int
-sha384_pw_cmp (char *userpwd, char *dbpwd )
+sha384_pw_cmp (const char *userpwd, const char *dbpwd )
{
return sha_pw_cmp( userpwd, dbpwd, SHA384_LENGTH );
}
int
-sha512_pw_cmp (char *userpwd, char *dbpwd )
+sha512_pw_cmp (const char *userpwd, const char *dbpwd )
{
return sha_pw_cmp( userpwd, dbpwd, SHA512_LENGTH );
}
@@ -233,25 +229,25 @@ sha512_pw_cmp (char *userpwd, char *dbpwd )
* Wrapper password encryption functions
*/
char *
-sha1_pw_enc( char *pwd )
+sha1_pw_enc( const char *pwd )
{
return sha_pw_enc( pwd, SHA1_LENGTH );
}
char *
-sha256_pw_enc( char *pwd )
+sha256_pw_enc( const char *pwd )
{
return sha_pw_enc( pwd, SHA256_LENGTH );
}
char *
-sha384_pw_enc( char *pwd )
+sha384_pw_enc( const char *pwd )
{
return sha_pw_enc( pwd, SHA384_LENGTH );
}
char *
-sha512_pw_enc( char *pwd )
+sha512_pw_enc( const char *pwd )
{
return sha_pw_enc( pwd, SHA512_LENGTH );
}
diff --git a/ldap/servers/plugins/pwdstorage/ssha_pwd.c b/ldap/servers/plugins/pwdstorage/ssha_pwd.c
index 048eee42..14b8d443 100644
--- a/ldap/servers/plugins/pwdstorage/ssha_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/ssha_pwd.c
@@ -74,7 +74,7 @@ ssha_rand_array(void *randx, size_t len)
}
SECStatus
-sha_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt, unsigned int secOID)
+sha_salted_hash(char *hash_out, const char *pwd, struct berval *salt, unsigned int secOID)
{
PK11Context *ctx;
unsigned int outLen;
@@ -108,7 +108,7 @@ sha_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt, unsigne
PK11_DigestBegin(ctx);
PK11_DigestOp(ctx, (unsigned char*)pwd, strlen(pwd));
PK11_DigestOp(ctx, (unsigned char*)(salt->bv_val), salt->bv_len);
- PK11_DigestFinal(ctx, hash_out, &outLen, shaLen);
+ PK11_DigestFinal(ctx, (unsigned char*)hash_out, &outLen, shaLen);
PK11_DestroyContext(ctx, 1);
if (outLen == shaLen)
rc = SECSuccess;
@@ -118,17 +118,17 @@ sha_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt, unsigne
}
else {
/*backward compatibility*/
- rc = PK11_HashBuf(secOID, hash_out, (unsigned char *)pwd, strlen(pwd));
+ rc = PK11_HashBuf(secOID, (unsigned char*)hash_out, (unsigned char *)pwd, strlen(pwd));
}
return rc;
}
char *
-salted_sha_pw_enc( char *pwd, unsigned int shaLen )
+salted_sha_pw_enc( const char *pwd, unsigned int shaLen )
{
- unsigned char hash[ MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH ];
- unsigned char *salt = hash + shaLen;
+ char hash[ MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH ];
+ char *salt = hash + shaLen;
struct berval saltval;
char *enc;
char *schemeName;
@@ -184,8 +184,7 @@ salted_sha_pw_enc( char *pwd, unsigned int shaLen )
sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
PWD_HASH_PREFIX_END );
- (void)ldif_base64_encode( hash, enc + 2 + schemeNameLen,
- (shaLen + SHA_SALT_LENGTH), -1 );
+ (void)PL_Base64Encode( hash, (shaLen + SHA_SALT_LENGTH), enc + 2 + schemeNameLen );
return( enc );
}
@@ -194,25 +193,25 @@ salted_sha_pw_enc( char *pwd, unsigned int shaLen )
* Wrapper functions for password encoding
*/
char *
-salted_sha1_pw_enc( char *pwd )
+salted_sha1_pw_enc( const char *pwd )
{
return salted_sha_pw_enc( pwd, SHA1_LENGTH );
}
char *
-salted_sha256_pw_enc( char *pwd )
+salted_sha256_pw_enc( const char *pwd )
{
return salted_sha_pw_enc( pwd, SHA256_LENGTH );
}
char *
-salted_sha384_pw_enc( char *pwd )
+salted_sha384_pw_enc( const char *pwd )
{
return salted_sha_pw_enc( pwd, SHA384_LENGTH );
}
char *
-salted_sha512_pw_enc( char *pwd )
+salted_sha512_pw_enc( const char *pwd )
{
return salted_sha_pw_enc( pwd, SHA512_LENGTH );
}
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index b0c9f4e7..dfc5765d 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -1308,9 +1308,14 @@ done:;
*/
int cl5ImportLDIF (const char *clDir, const char *ldifFile, Object **replicas)
{
- FILE *file;
+#if defined(USE_OPENLDAP)
+ LDIFFP *file = NULL;
+ int buflen;
+#else
+ FILE *file = NULL;
+#endif
int rc;
- char *buff;
+ char *buff = NULL;
int lineno = 0;
slapi_operation_parameters op;
Object *replica = NULL;
@@ -1345,7 +1350,11 @@ int cl5ImportLDIF (const char *clDir, const char *ldifFile, Object **replicas)
}
/* open LDIF file */
+#if defined(USE_OPENLDAP)
+ file = ldif_open (ldifFile, "r");
+#else
file = fopen (ldifFile, "r"); /* XXXggood Does fopen reliably work if > 255 files open? */
+#endif
if (file == NULL)
{
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
@@ -1374,10 +1383,14 @@ int cl5ImportLDIF (const char *clDir, const char *ldifFile, Object **replicas)
}
/* read entries and write them to changelog */
+#if defined(USE_OPENLDAP)
+ while (ldif_read_record( file, &lineno, &buff, &buflen ))
+#else
while ((buff = ldif_get_entry( file, &lineno )) != NULL)
+#endif
{
rc = _cl5LDIF2Operation (buff, &op, &replGen);
- slapi_ch_free ((void**)&buff);
+ slapi_ch_free_string(&buff);
if (rc != CL5_SUCCESS)
{
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
@@ -1394,7 +1407,7 @@ int cl5ImportLDIF (const char *clDir, const char *ldifFile, Object **replicas)
"cl5ImportLDIF: failed to locate replica for target dn (%s) and "
"replica generation %s\n", op.target_address.dn, replGen);
- slapi_ch_free ((void**)&replGen);
+ slapi_ch_free_string(&replGen);
operation_parameters_done (&op);
goto done;
}
@@ -1409,18 +1422,25 @@ int cl5ImportLDIF (const char *clDir, const char *ldifFile, Object **replicas)
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl,
"cl5ImportLDIF: failed to write operation to the changelog\n");
object_release (replica);
- slapi_ch_free ((void**)&replGen);
+ slapi_ch_free_string(&replGen);
operation_parameters_done (&op);
goto done;
}
}
object_release (replica);
- slapi_ch_free ((void**)&replGen);
+ slapi_ch_free_string(&replGen);
operation_parameters_done (&op);
}
done:;
+ if (file) {
+#if defined(USE_OPENLDAP)
+ ldif_close(file);
+#else
+ fclose(file);
+#endif
+ }
_cl5Close ();
PR_RWLock_Unlock (s_cl5Desc.stLock);
return rc;
@@ -5041,46 +5061,46 @@ static int _cl5Operation2LDIF (const slapi_operation_parameters *op, const char
}
/* fill buffer */
- ldif_put_type_and_value(&buff, T_CHANGETYPESTR, (char*)strType, strlen (strType));
- ldif_put_type_and_value(&buff, T_REPLGEN, (char*)replGen, strlen (replGen));
- ldif_put_type_and_value(&buff, T_CSNSTR, (char*)strCSN, strlen (strCSN));
- ldif_put_type_and_value(&buff, T_UNIQUEIDSTR, op->target_address.uniqueid,
- strlen (op->target_address.uniqueid));
+ slapi_ldif_put_type_and_value_with_options(&buff, T_CHANGETYPESTR, (char*)strType, strlen (strType), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_REPLGEN, (char*)replGen, strlen (replGen), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_CSNSTR, (char*)strCSN, strlen (strCSN), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_UNIQUEIDSTR, op->target_address.uniqueid,
+ strlen (op->target_address.uniqueid), 0);
switch (op->operation_type)
{
case SLAPI_OPERATION_ADD: if (op->p.p_add.parentuniqueid)
- ldif_put_type_and_value(&buff, T_PARENTIDSTR,
- op->p.p_add.parentuniqueid, strlen (op->p.p_add.parentuniqueid));
- ldif_put_type_and_value(&buff, T_DNSTR, rawDN, strlen (rawDN));
- ldif_put_type_and_value(&buff, T_CHANGESTR, l->ls_buf, l->ls_len);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_PARENTIDSTR,
+ op->p.p_add.parentuniqueid, strlen (op->p.p_add.parentuniqueid), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_DNSTR, rawDN, strlen (rawDN), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_CHANGESTR, l->ls_buf, l->ls_len, 0);
slapi_ch_free ((void**)&rawDN);
break;
- case SLAPI_OPERATION_MODIFY: ldif_put_type_and_value(&buff, T_DNSTR, op->target_address.dn,
- strlen (op->target_address.dn));
- ldif_put_type_and_value(&buff, T_CHANGESTR, l->ls_buf, l->ls_len);
+ case SLAPI_OPERATION_MODIFY: slapi_ldif_put_type_and_value_with_options(&buff, T_DNSTR, op->target_address.dn,
+ strlen (op->target_address.dn), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_CHANGESTR, l->ls_buf, l->ls_len, 0);
break;
- case SLAPI_OPERATION_MODRDN: ldif_put_type_and_value(&buff, T_DNSTR, op->target_address.dn,
- strlen (op->target_address.dn));
- ldif_put_type_and_value(&buff, T_NEWRDNSTR, op->p.p_modrdn.modrdn_newrdn,
- strlen (op->p.p_modrdn.modrdn_newrdn));
- ldif_put_type_and_value(&buff, T_DRDNFLAGSTR, strDeleteOldRDN,
- strlen (strDeleteOldRDN));
+ case SLAPI_OPERATION_MODRDN: slapi_ldif_put_type_and_value_with_options(&buff, T_DNSTR, op->target_address.dn,
+ strlen (op->target_address.dn), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_NEWRDNSTR, op->p.p_modrdn.modrdn_newrdn,
+ strlen (op->p.p_modrdn.modrdn_newrdn), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_DRDNFLAGSTR, strDeleteOldRDN,
+ strlen (strDeleteOldRDN), 0);
if (op->p.p_modrdn.modrdn_newsuperior_address.dn)
- ldif_put_type_and_value(&buff, T_NEWSUPERIORDNSTR,
+ slapi_ldif_put_type_and_value_with_options(&buff, T_NEWSUPERIORDNSTR,
op->p.p_modrdn.modrdn_newsuperior_address.dn,
- strlen (op->p.p_modrdn.modrdn_newsuperior_address.dn));
+ strlen (op->p.p_modrdn.modrdn_newsuperior_address.dn), 0);
if (op->p.p_modrdn.modrdn_newsuperior_address.uniqueid)
- ldif_put_type_and_value(&buff, T_NEWSUPERIORIDSTR,
+ slapi_ldif_put_type_and_value_with_options(&buff, T_NEWSUPERIORIDSTR,
op->p.p_modrdn.modrdn_newsuperior_address.uniqueid,
- strlen (op->p.p_modrdn.modrdn_newsuperior_address.uniqueid));
- ldif_put_type_and_value(&buff, T_CHANGESTR, l->ls_buf, l->ls_len);
+ strlen (op->p.p_modrdn.modrdn_newsuperior_address.uniqueid), 0);
+ slapi_ldif_put_type_and_value_with_options(&buff, T_CHANGESTR, l->ls_buf, l->ls_len, 0);
break;
- case SLAPI_OPERATION_DELETE: ldif_put_type_and_value(&buff, T_DNSTR, op->target_address.dn,
- strlen (op->target_address.dn));
+ case SLAPI_OPERATION_DELETE: slapi_ldif_put_type_and_value_with_options(&buff, T_DNSTR, op->target_address.dn,
+ strlen (op->target_address.dn), 0);
break;
}
@@ -5101,7 +5121,11 @@ static int
_cl5LDIF2Operation (char *ldifEntry, slapi_operation_parameters *op, char **replGen)
{
int rc;
+#if defined(USE_OPENLDAP)
+ ber_len_t vlen;
+#else
int vlen;
+#endif
char *next, *line;
char *type, *value;
Slapi_Mods *mods;
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 5a171cb5..47d07be4 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -52,8 +52,14 @@ replica locked. Seems like right thing to do.
*/
#include "repl5.h"
+#if defined(USE_OPENLDAP)
+#include "ldap.h"
+#else
#include "ldappr.h"
#include "ldap-extension.h"
+#endif
+#include "nspr.h"
+#include "private/pprio.h"
#include "nss.h"
typedef struct repl_connection
@@ -365,7 +371,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retda
if (0 == rc)
{
/* Timeout */
- rc = ldap_get_lderrno(conn->ld, NULL, NULL);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, NULL);
conn->last_ldap_error = LDAP_TIMEOUT;
return_value = CONN_TIMEOUT;
}
@@ -383,7 +389,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retda
/* Error */
char *s = NULL;
- rc = ldap_get_lderrno(conn->ld, NULL, &s);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, &s);
conn->last_ldap_errmsg = s;
conn->last_ldap_error = rc;
/* some errors will require a disconnect and retry the connection
@@ -485,6 +491,61 @@ conn_read_result(Repl_Connection *conn, int *message_id)
* on the same connection), we need to _first_ verify that the connection
* is writable. If it isn't, we can deadlock if we proceed any further...
*/
+#if defined(USE_OPENLDAP)
+/* openldap has LBER_SB_OPT_DATA_READY but that doesn't really
+ work for our purposes - so we grab the openldap fd from the
+ ber sockbuf layer, import it into a PR Poll FD, then
+ do the poll
+*/
+static ConnResult
+see_if_write_available(Repl_Connection *conn, PRIntervalTime timeout)
+{
+ PRFileDesc *pollfd = NULL;
+ PRPollDesc polldesc;
+ ber_socket_t fd = 0;
+ int rc;
+
+ /* get the sockbuf */
+ ldap_get_option(conn->ld, LDAP_OPT_DESC, &fd);
+ if (fd <= 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "%s: invalid connection insee_if_write_available \n",
+ agmt_get_long_name(conn->agmt));
+ conn->last_ldap_error = LDAP_PARAM_ERROR;
+ return CONN_OPERATION_FAILED;
+ }
+ /* wrap the sockbuf fd with a NSPR FD created especially
+ for use with polling, and only with polling */
+ pollfd = PR_CreateSocketPollFd(fd);
+ polldesc.fd = pollfd;
+ polldesc.in_flags = PR_POLL_WRITE|PR_POLL_EXCEPT;
+ polldesc.out_flags = 0;
+
+ /* do the poll */
+ rc = PR_Poll(&polldesc, 1, timeout);
+
+ /* unwrap the socket */
+ PR_DestroySocketPollFd(pollfd);
+
+ /* check */
+ if (rc == 0) { /* timeout */
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: poll timed out - poll interval [%d]\n",
+ agmt_get_long_name(conn->agmt),
+ timeout);
+ return CONN_TIMEOUT;
+ } else if ((rc < 0) || ((polldesc.out_flags|PR_POLL_WRITE) == 0)) { /* error */
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: error during poll attempt [%d:%s]\n",
+ agmt_get_long_name(conn->agmt),
+ PR_GetError(), slapd_pr_strerror(PR_GetError()));
+ conn->last_ldap_error = LDAP_PARAM_ERROR;
+ return CONN_OPERATION_FAILED;
+ }
+
+ return CONN_OPERATION_SUCCESS;
+}
+#else /* ! USE_OPENLDAP */
/* Since we're poking around with ldap c sdk internals, we have to
be careful since the PR layer stores different session and socket
info than the NSS SSL layer than the SASL layer - and they all
@@ -504,7 +565,7 @@ see_if_write_available(Repl_Connection *conn, PRIntervalTime timeout)
memset(&iofns, 0, sizeof(iofns));
iofns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
if (ldap_get_option(conn->ld, LDAP_X_OPT_EXTIO_FN_PTRS, &iofns) < 0) {
- rc = ldap_get_lderrno(conn->ld, NULL, NULL);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, NULL);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Failed call to ldap_get_option to get extiofns in "
"see_if_write_available: LDAP error %d (%s)\n",
@@ -517,7 +578,7 @@ see_if_write_available(Repl_Connection *conn, PRIntervalTime timeout)
/* set up the poll structure */
if (ldap_get_option(conn->ld, LDAP_OPT_DESC, &pollstr.lpoll_fd) < 0) {
- rc = ldap_get_lderrno(conn->ld, NULL, NULL);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, NULL);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Failed call to ldap_get_option for poll_fd in "
"see_if_write_available: LDAP error %d (%s)\n",
@@ -529,7 +590,7 @@ see_if_write_available(Repl_Connection *conn, PRIntervalTime timeout)
if (ldap_get_option(conn->ld, LDAP_X_OPT_SOCKETARG,
&pollstr.lpoll_socketarg) < 0) {
- rc = ldap_get_lderrno(conn->ld, NULL, NULL);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, NULL);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Failed call to ldap_get_option for socketarg in "
"see_if_write_available: LDAP error %d (%s)\n",
@@ -553,6 +614,7 @@ see_if_write_available(Repl_Connection *conn, PRIntervalTime timeout)
return CONN_OPERATION_SUCCESS;
}
+#endif /* ! USE_OPENLDAP */
/*
* Common code to send an LDAPv3 operation and collect the result.
@@ -1010,7 +1072,9 @@ conn_connect(Repl_Connection *conn)
}
if (return_value == CONN_OPERATION_SUCCESS) {
+#if !defined(USE_OPENLDAP)
int io_timeout_ms;
+#endif
/* Now we initialize the LDAP Structure and set options */
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
@@ -1055,10 +1119,13 @@ conn_connect(Repl_Connection *conn)
ldap_set_option(conn->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
/* override the default timeout with the specified timeout */
+#if defined(USE_OPENLDAP)
+ ldap_set_option(conn->ld, LDAP_OPT_NETWORK_TIMEOUT, &conn->timeout);
+#else
io_timeout_ms = conn->timeout.tv_sec * 1000 + conn->timeout.tv_usec / 1000;
prldap_set_session_option(conn->ld, NULL, PRLDAP_OPT_IO_MAX_TIMEOUT,
io_timeout_ms);
-
+#endif
/* We've got an ld. Now bind to the server. */
conn->last_operation = CONN_BIND;
@@ -1066,7 +1133,7 @@ conn_connect(Repl_Connection *conn)
if ( bind_and_check_pwp(conn, binddn, conn->plain) == CONN_OPERATION_FAILED )
{
- conn->last_ldap_error = ldap_get_lderrno (conn->ld, NULL, NULL);
+ conn->last_ldap_error = slapi_ldap_get_lderrno (conn->ld, NULL, NULL);
conn->state = STATE_DISCONNECTED;
return_value = CONN_OPERATION_FAILED;
}
@@ -1308,36 +1375,38 @@ attribute_string_value_present(LDAP *ld, LDAPMessage *entry, const char *type,
const char *value)
{
int return_value = 0;
+ ber_len_t vallen;
if (NULL != entry)
{
char *atype = NULL;
BerElement *ber = NULL;
+ vallen = strlen(value);
atype = ldap_first_attribute(ld, entry, &ber);
while (NULL != atype && 0 == return_value)
{
if (strcasecmp(atype, type) == 0)
{
- char **strvals = ldap_get_values(ld, entry, atype);
+ struct berval **vals = ldap_get_values_len(ld, entry, atype);
int i;
- for (i = 0; return_value == 0 && NULL != strvals && NULL != strvals[i]; i++)
+ for (i = 0; return_value == 0 && NULL != vals && NULL != vals[i]; i++)
{
- if (strcmp(strvals[i], value) == 0)
+ if ((vallen == vals[i]->bv_len) && !strncmp(vals[i]->bv_val, value, vallen))
{
return_value = 1;
}
}
- if (NULL != strvals)
+ if (NULL != vals)
{
- ldap_value_free(strvals);
+ ldap_value_free_len(vals);
}
}
ldap_memfree(atype);
atype = ldap_next_attribute(ld, entry, ber);
}
if (NULL != ber)
- ldap_ber_free(ber, 0);
+ ber_free(ber, 0);
/* The last atype has not been freed yet */
if (NULL != atype)
ldap_memfree(atype);
@@ -1659,7 +1728,7 @@ bind_and_check_pwp(Repl_Connection *conn, char * binddn, char *password)
char *errmsg = NULL;
conn->last_ldap_error = rc;
/* errmsg is a pointer directly into the ld structure - do not free */
- rc = ldap_get_lderrno( ld, NULL, &errmsg );
+ rc = slapi_ldap_get_lderrno( ld, NULL, &errmsg );
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Replication bind with %s auth failed: LDAP error %d (%s) (%s)\n",
agmt_get_long_name(conn->agmt),
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 30b7ee9c..5f280b1d 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1011,10 +1011,10 @@ replica_set_referrals(Replica *r,const Slapi_ValueSet *vs)
while (vv)
{
const char *ref = slapi_value_get_string(vv);
- struct ldap_url_desc *lud = NULL;
- int myrc = ldap_url_parse(ref, &lud);
+ LDAPURLDesc *lud = NULL;
+ int myrc = slapi_ldap_url_parse(ref, &lud, 0, NULL);
/* see if the dn is already in the referral URL */
- if (myrc == LDAP_URL_ERR_NODN || !lud || !lud->lud_dn) {
+ if (!lud || !lud->lud_dn) {
/* add the dn */
Slapi_Value *newval = NULL;
int len = strlen(ref);
diff --git a/ldap/servers/plugins/replication/repl5_total.c b/ldap/servers/plugins/replication/repl5_total.c
index e82d8da3..a555bec6 100644
--- a/ldap/servers/plugins/replication/repl5_total.c
+++ b/ldap/servers/plugins/replication/repl5_total.c
@@ -472,7 +472,7 @@ static int
my_ber_scanf_value(BerElement *ber, Slapi_Value **value, PRBool *deleted)
{
struct berval *attrval = NULL;
- ber_len_t len;
+ ber_len_t len = -1;
ber_tag_t tag;
CSN *csn = NULL;
char csnstring[CSN_STRSIZE + 1];
diff --git a/ldap/servers/plugins/replication/replutil.c b/ldap/servers/plugins/replication/replutil.c
index c1a86255..8703c7c2 100644
--- a/ldap/servers/plugins/replication/replutil.c
+++ b/ldap/servers/plugins/replication/replutil.c
@@ -381,9 +381,9 @@ make_changes_string(LDAPMod **ldm, char **includeattrs)
ldm[ i ]->mod_bvalues[ j ]->bv_len ) + 1;
buf = slapi_ch_malloc( len );
bufp = buf;
- ldif_put_type_and_value( &bufp, ldm[ i ]->mod_type,
+ slapi_ldif_put_type_and_value_with_options( &bufp, ldm[ i ]->mod_type,
ldm[ i ]->mod_bvalues[ j ]->bv_val,
- ldm[ i ]->mod_bvalues[ j ]->bv_len );
+ ldm[ i ]->mod_bvalues[ j ]->bv_len, 0 );
*bufp = '\0';
addlenstr( l, buf );
@@ -739,10 +739,10 @@ repl_set_mtn_state_and_referrals(
/* next, add the repl root dn to each referral if not present */
for (ii = 0; referrals_to_set && referrals_to_set[ii]; ++ii) {
- struct ldap_url_desc *lud = NULL;
- int myrc = ldap_url_parse(referrals_to_set[ii], &lud);
+ LDAPURLDesc *lud = NULL;
+ int myrc = slapi_ldap_url_parse(referrals_to_set[ii], &lud, 0, NULL);
/* see if the dn is already in the referral URL */
- if (myrc == LDAP_URL_ERR_NODN || !lud || !lud->lud_dn) {
+ if (!lud || !lud->lud_dn) {
/* add the dn */
int len = strlen(referrals_to_set[ii]);
const char *cdn = slapi_sdn_get_dn(repl_root_sdn);
diff --git a/ldap/servers/plugins/replication/urp_glue.c b/ldap/servers/plugins/replication/urp_glue.c
index 6bceb5a0..15b29d41 100644
--- a/ldap/servers/plugins/replication/urp_glue.c
+++ b/ldap/servers/plugins/replication/urp_glue.c
@@ -186,7 +186,7 @@ do_create_glue_entry(const Slapi_RDN *rdn, const Slapi_DN *superiordn, const cha
rdnstr = slapi_ch_realloc(rdnstr, alloc_len);
rdnpair = &rdnstr[rdnstr_len];
}
- ldif_put_type_and_value_with_options(&rdnpair, rdntype,
+ slapi_ldif_put_type_and_value_with_options(&rdnpair, rdntype,
rdnval, rdnval_len, LDIF_OPT_NOWRAP);
*rdnpair = '\0';
}
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
index 01b61cf9..b9643b5f 100644
--- a/ldap/servers/plugins/replication/windows_connection.c
+++ b/ldap/servers/plugins/replication/windows_connection.c
@@ -53,7 +53,9 @@ replica locked. Seems like right thing to do.
#include "repl5.h"
#include "windowsrepl.h"
+#if !defined(USE_OPENLDAP)
#include "ldappr.h"
+#endif
#include "slap.h"
#include "nss.h"
@@ -352,7 +354,7 @@ windows_perform_operation(Repl_Connection *conn, int optype, const char *dn,
if (0 == rc)
{
/* Timeout */
- rc = ldap_get_lderrno(conn->ld, NULL, NULL);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, NULL);
conn->last_ldap_error = LDAP_TIMEOUT;
return_value = CONN_TIMEOUT;
}
@@ -361,7 +363,7 @@ windows_perform_operation(Repl_Connection *conn, int optype, const char *dn,
/* Error */
char *s = NULL;
- rc = ldap_get_lderrno(conn->ld, NULL, &s);
+ rc = slapi_ldap_get_lderrno(conn->ld, NULL, &s);
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Received error %d: %s for %s operation\n",
agmt_get_long_name(conn->agmt),
@@ -591,7 +593,7 @@ windows_LDAPMessage2Entry(Repl_Connection *conn, LDAPMessage * msg, int attrsonl
}
if ( NULL != ber )
{
- ldap_ber_free( ber, 0 );
+ ber_free( ber, 0 );
}
windows_private_set_raw_entry(conn->agmt, rawentry); /* windows private now owns rawentry */
@@ -1214,7 +1216,9 @@ windows_conn_connect(Repl_Connection *conn)
}
if (return_value == CONN_OPERATION_SUCCESS) {
+#if !defined(USE_OPENLDAP)
int io_timeout_ms;
+#endif
/* Now we initialize the LDAP Structure and set options */
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
@@ -1260,10 +1264,13 @@ windows_conn_connect(Repl_Connection *conn)
ldap_set_option(conn->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
/* override the default timeout with the specified timeout */
+#if defined(USE_OPENLDAP)
+ ldap_set_option(conn->ld, LDAP_OPT_NETWORK_TIMEOUT, &conn->timeout);
+#else
io_timeout_ms = conn->timeout.tv_sec * 1000 + conn->timeout.tv_usec / 1000;
prldap_set_session_option(conn->ld, NULL, PRLDAP_OPT_IO_MAX_TIMEOUT,
io_timeout_ms);
-
+#endif
/* We've got an ld. Now bind to the server. */
conn->last_operation = CONN_BIND;
@@ -1271,7 +1278,7 @@ windows_conn_connect(Repl_Connection *conn)
if ( bind_and_check_pwp(conn, binddn, conn->plain) == CONN_OPERATION_FAILED )
{
- conn->last_ldap_error = ldap_get_lderrno (conn->ld, NULL, NULL);
+ conn->last_ldap_error = slapi_ldap_get_lderrno (conn->ld, NULL, NULL);
conn->state = STATE_DISCONNECTED;
return_value = CONN_OPERATION_FAILED;
}
@@ -1594,6 +1601,7 @@ attribute_string_value_present(LDAP *ld, LDAPMessage *entry, const char *type,
const char *value)
{
int return_value = 0;
+ ber_len_t vallen;
LDAPDebug( LDAP_DEBUG_TRACE, "=> attribute_string_value_present\n", 0, 0, 0 );
@@ -1602,30 +1610,31 @@ attribute_string_value_present(LDAP *ld, LDAPMessage *entry, const char *type,
char *atype = NULL;
BerElement *ber = NULL;
+ vallen = strlen(value);
atype = ldap_first_attribute(ld, entry, &ber);
while (NULL != atype && 0 == return_value)
{
if (strcasecmp(atype, type) == 0)
{
- char **strvals = ldap_get_values(ld, entry, atype);
+ struct berval **vals = ldap_get_values_len(ld, entry, atype);
int i;
- for (i = 0; return_value == 0 && NULL != strvals && NULL != strvals[i]; i++)
+ for (i = 0; return_value == 0 && NULL != vals && NULL != vals[i]; i++)
{
- if (strcmp(strvals[i], value) == 0)
+ if ((vallen == vals[i]->bv_len) && !strncmp(vals[i]->bv_val, value, vallen))
{
return_value = 1;
}
}
- if (NULL != strvals)
+ if (NULL != vals)
{
- ldap_value_free(strvals);
+ ldap_value_free_len(vals);
}
}
ldap_memfree(atype);
atype = ldap_next_attribute(ld, entry, ber);
}
if (NULL != ber)
- ldap_ber_free(ber, 0);
+ ber_free(ber, 0);
/* The last atype has not been freed yet */
if (NULL != atype)
ldap_memfree(atype);
@@ -1768,7 +1777,7 @@ bind_and_check_pwp(Repl_Connection *conn, char * binddn, char *password)
char *errmsg = NULL;
conn->last_ldap_error = rc;
/* errmsg is a pointer directly into the ld structure - do not free */
- rc = ldap_get_lderrno( ld, NULL, &errmsg );
+ rc = slapi_ldap_get_lderrno( ld, NULL, &errmsg );
slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
"%s: Replication bind with %s auth failed: LDAP error %d (%s) (%s)\n",
agmt_get_long_name(conn->agmt),
@@ -1816,13 +1825,13 @@ do_simple_bind (Repl_Connection *conn, LDAP *ld, char * binddn, char *password)
LDAPDebug( LDAP_DEBUG_TRACE, "=> do_simple_bind\n", 0, 0, 0 );
- if( ( msgid = ldap_simple_bind( ld, binddn, password ) ) == -1 )
+ if( ( msgid = slapi_ldap_bind( ld, binddn, password, LDAP_SASL_SIMPLE, NULL, NULL, NULL, &msgid ) ) == -1 )
{
char *ldaperrtext = NULL;
int ldaperr;
int prerr = PR_GetError();
- ldaperr = ldap_get_lderrno( ld, NULL, &ldaperrtext );
+ ldaperr = slapi_ldap_get_lderrno( ld, NULL, &ldaperrtext );
/* Do not report the same error over and over again */
if (conn->last_ldap_error != ldaperr)
{
diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c
index d9844b83..a29fefbe 100644
--- a/ldap/servers/plugins/retrocl/retrocl_po.c
+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
@@ -126,9 +126,9 @@ static lenstr *make_changes_string(LDAPMod **ldm, const char **includeattrs)
ldm[ i ]->mod_bvalues[ j ]->bv_len ) + 1;
buf = slapi_ch_malloc( len );
bufp = buf;
- ldif_put_type_and_value( &bufp, ldm[ i ]->mod_type,
+ slapi_ldif_put_type_and_value_with_options( &bufp, ldm[ i ]->mod_type,
ldm[ i ]->mod_bvalues[ j ]->bv_val,
- ldm[ i ]->mod_bvalues[ j ]->bv_len );
+ ldm[ i ]->mod_bvalues[ j ]->bv_len, 0 );
*bufp = '\0';
addlenstr( l, buf );
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 1bd2d2f2..df683a90 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -80,7 +80,7 @@ do_add( Slapi_PBlock *pb )
Slapi_Operation *operation;
BerElement *ber;
char *last;
- ber_len_t len;
+ ber_len_t len = -1;
ber_tag_t tag;
Slapi_Entry *e = NULL;
int err;
@@ -130,6 +130,7 @@ do_add( Slapi_PBlock *pb )
tag = ber_next_element( ber, &len, last ) ) {
char *type = NULL, *normtype = NULL;
struct berval **vals = NULL;
+ len = -1; /* reset - not used in loop */
if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
@@ -196,7 +197,7 @@ do_add( Slapi_PBlock *pb )
goto free_and_return;
}
- if ( tag == LBER_DEFAULT ) {
+ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c
index 7a757845..3cca975f 100644
--- a/ldap/servers/slapd/auditlog.c
+++ b/ldap/servers/slapd/auditlog.c
@@ -195,9 +195,9 @@ write_audit_file(
len = LDIF_SIZE_NEEDED( len, mods[j]->mod_bvalues[i]->bv_len ) + 1;
buf = slapi_ch_malloc( len );
bufp = buf;
- ldif_put_type_and_value( &bufp, mods[j]->mod_type,
+ slapi_ldif_put_type_and_value_with_options( &bufp, mods[j]->mod_type,
mods[j]->mod_bvalues[i]->bv_val,
- mods[j]->mod_bvalues[i]->bv_len );
+ mods[j]->mod_bvalues[i]->bv_len, 0 );
*bufp = '\0';
addlenstr( l, buf );
slapi_ch_free( (void**)&buf );
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 064b3318..3a500eb7 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -83,7 +83,7 @@ slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
LDAPControl **ctrls;
if (ld != internal_ld) {
- return ldap_search_s (ld, baseDN, scope, filter, attrs, attrsonly, result);
+ return ldap_search_ext_s (ld, baseDN, scope, filter, attrs, attrsonly, NULL, NULL, NULL, -1, result);
}
LDAPDebug (LDAP_DEBUG_TRACE, "=> slapu_search_s (\"%s\", %i, %s)\n",
baseDN, scope, filter);
@@ -240,7 +240,7 @@ static void LDAP_CALL LDAP_CALLBACK
slapu_ber_free( LDAP* ld, BerElement* iter, int freebuf )
{
if (ld != internal_ld) {
- ldap_ber_free (iter, freebuf);
+ ber_free (iter, freebuf);
} else {
free ((Slapi_Attr**)iter);
}
diff --git a/ldap/servers/slapd/back-ldbm/ancestorid.c b/ldap/servers/slapd/back-ldbm/ancestorid.c
index c3edea06..59d77223 100644
--- a/ldap/servers/slapd/back-ldbm/ancestorid.c
+++ b/ldap/servers/slapd/back-ldbm/ancestorid.c
@@ -904,8 +904,8 @@ int slapi_sdn_suffix_cmp(
slapi_sdn_get_dn(common), 0, 0);
out:
- ldap_value_free(rdns1);
- ldap_value_free(rdns2);
+ slapi_ldap_value_free(rdns1);
+ slapi_ldap_value_free(rdns2);
LDAPDebug(LDAP_DEBUG_TRACE, "slapi_sdn_suffix_cmp(<%s>, <%s>) => %d\n",
slapi_sdn_get_dn(left), slapi_sdn_get_dn(right), ret);
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index 7cde2bfc..e0f00750 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -274,7 +274,11 @@ import_get_version(char *str)
char *valuecharptr;
char *mystr, *ms;
int offset;
+#if defined(USE_OPENLDAP)
+ ber_len_t valuelen;
+#else
int valuelen;
+#endif
int my_version = 0;
int retmalloc = 0;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
index d13495b9..eccf8543 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
@@ -44,8 +44,6 @@
#include "back-ldbm.h"
-extern char **str2charray();
-
struct attrinfo *
attrinfo_new()
{
@@ -186,11 +184,11 @@ attr_index_config(
char *p;
int *substrlens = NULL;
- attrs = str2charray( argv[0], "," );
+ attrs = slapi_str2charray( argv[0], "," );
if ( argc > 1 ) {
- indexes = str2charray( argv[1], "," );
+ indexes = slapi_str2charray( argv[1], "," );
if ( argc > 2 ) {
- index_rules = str2charray( argv[2], "," );
+ index_rules = slapi_str2charray( argv[2], "," );
}
}
for ( i = 0; attrs[i] != NULL; i++ ) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index bc6215a6..5aa3669b 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -1132,7 +1132,7 @@ ldbm_config_exclude_from_export_set( void *arg, void *value, char *errorbuf,
if ( NULL != value ) {
char *dupvalue = slapi_ch_strdup( value );
- li->li_attrs_to_exclude_from_export = str2charray( dupvalue, " " );
+ li->li_attrs_to_exclude_from_export = slapi_str2charray( dupvalue, " " );
slapi_ch_free((void**)&dupvalue);
}
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
index ba7789bc..7df0b892 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
@@ -415,8 +415,8 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
origIndexTypes = attrinfo2ConfIndexes(ainfo);
origMatchingRules = attrinfo2ConfMatchingRules(ainfo);
- origIndexTypesArray = str2charray(origIndexTypes, ",");
- origMatchingRulesArray = str2charray(origMatchingRules, ",");
+ origIndexTypesArray = slapi_str2charray(origIndexTypes, ",");
+ origMatchingRulesArray = slapi_str2charray(origMatchingRules, ",");
for (i = 0; mods[i] != NULL; i++) {
config_attr = (char *)mods[i]->mod_type;
@@ -621,13 +621,13 @@ int ldbm_instance_config_add_index_entry(
}
PL_strncpyz(tmpAttrsStr,argv[0], sizeof(tmpAttrsStr));
- attrs = str2charray( tmpAttrsStr, "," );
+ attrs = slapi_str2charray( tmpAttrsStr, "," );
PL_strncpyz(tmpIndexesStr,argv[1], sizeof(tmpIndexesStr));
- indexes = str2charray( tmpIndexesStr, ",");
+ indexes = slapi_str2charray( tmpIndexesStr, ",");
if(argc > 2) {
PL_strncpyz(tmpMatchingRulesStr,argv[2], sizeof(tmpMatchingRulesStr));
- matchingRules = str2charray( tmpMatchingRulesStr, ",");
+ matchingRules = slapi_str2charray( tmpMatchingRulesStr, ",");
}
for(i=0; attrs[i] !=NULL; i++)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index c71dd8ee..ce4c8797 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -660,7 +660,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
}
}
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
if (DB_LOCK_DEADLOCK == retval)
{
/* Retry txn */
@@ -1055,8 +1055,8 @@ moddn_newrdn_mods(Slapi_PBlock *pb, const char *olddn, struct backentry *ec, Sla
*/
if (!op_shared_is_allowed_attr (type, is_repl_op))
{
- ldap_value_free( rdns );
- ldap_value_free( dns );
+ slapi_ldap_value_free( rdns );
+ slapi_ldap_value_free( dns );
slapi_ch_free_string(&dn);
return LDAP_UNWILLING_TO_PERFORM;
}
@@ -1064,13 +1064,13 @@ moddn_newrdn_mods(Slapi_PBlock *pb, const char *olddn, struct backentry *ec, Sla
slapi_mods_add_modbvps( smods_wsi, LDAP_MOD_DELETE, type, bvps );
}
}
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
}
else
{
badrdn = 1;
}
- ldap_value_free( dns );
+ slapi_ldap_value_free( dns );
}
else
{
@@ -1106,7 +1106,7 @@ moddn_newrdn_mods(Slapi_PBlock *pb, const char *olddn, struct backentry *ec, Sla
slapi_mods_add_modbvps( smods_wsi, LDAP_MOD_ADD, type, bvps );
}
}
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
}
else
{
@@ -1313,7 +1313,7 @@ moddn_rename_child_entry(
strcat(newdn,", ");
}
}
- ldap_value_free( olddns );
+ slapi_ldap_value_free( olddns );
slapi_entry_set_dn( ec->ep_entry, newdn );
add_update_entrydn_operational_attributes (ec);
@@ -1369,7 +1369,7 @@ moddn_rename_children(
char **parentdns;
parentdns = ldap_explode_dn( slapi_sdn_get_dn(dn_parentdn), 0 );
for(;parentdns[parentdncomps]!=NULL;parentdncomps++);
- ldap_value_free( parentdns );
+ slapi_ldap_value_free( parentdns );
}
/*
@@ -1392,7 +1392,7 @@ moddn_rename_children(
i++;
}
}
- ldap_value_free( newsuperiordns );
+ slapi_ldap_value_free( newsuperiordns );
return retval;
}
diff --git a/ldap/servers/slapd/back-ldbm/sort.c b/ldap/servers/slapd/back-ldbm/sort.c
index 2694338e..639fdd52 100644
--- a/ldap/servers/slapd/back-ldbm/sort.c
+++ b/ldap/servers/slapd/back-ldbm/sort.c
@@ -294,7 +294,7 @@ int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps)
BerElement *ber = NULL;
sort_spec_thing *listhead = NULL;
ber_tag_t tag = 0;
- ber_len_t len = 0;
+ ber_len_t len = -1;
char *last = NULL;
sort_spec_thing *listpointer = NULL;
char *type = NULL;
@@ -318,6 +318,7 @@ int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps)
sort_spec_thing *s = NULL;
ber_tag_t return_value;
+ len = -1; /* reset - not used here */
next_tag = ber_first_element( ber, &len, &inner_last );
/* The type is not optional */
@@ -334,6 +335,7 @@ int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps)
/* Now look for the next tag. */
+ len = -1; /* reset - not used here */
next_tag = ber_next_element(ber,&len, inner_last);
/* Are we done ? */
@@ -343,6 +345,7 @@ int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps)
/* If so, get it */
ber_scanf(ber,"a",&matchrule);
/* That can be followed by a reverse indicator */
+ len = -1; /* reset - not used here */
next_tag = ber_next_element(ber,&len, inner_last);
if (LDAP_TAG_SK_REVERSE == next_tag) {
/* Get the reverse sort indicator here */
@@ -355,7 +358,7 @@ int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps)
}
} else {
/* Perhaps we're done now ? */
- if (LBER_END_OF_SEQORSET != next_tag) {
+ if ((LBER_END_OF_SEQORSET != next_tag) && (len != -1)) {
/* Protocol error---we got a matching rule, but followed by something other
* than reverse or end of sequence.
*/
@@ -390,7 +393,7 @@ int parse_sort_spec(struct berval *sort_spec_ber, sort_spec **ps)
if (NULL == listhead) {
listhead = s;
}
-
+ len = -1; /* reset for next loop iter */
}
if (NULL == listhead) { /* LP - defect #559792 - don't return null listhead */
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c
index 63c63485..af68d1c5 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c
@@ -567,7 +567,7 @@ vlvIndex_delete(struct vlvIndex** ppvs)
}
}
}
- ldap_free_sort_keylist((*ppvs)->vlv_sortkey);
+ internal_ldap_free_sort_keylist((*ppvs)->vlv_sortkey);
attrinfo_delete(&((*ppvs)->vlv_attrinfo));
slapi_ch_free((void**)&((*ppvs)->vlv_name));
slapi_ch_free((void**)&((*ppvs)->vlv_filename));
@@ -602,7 +602,7 @@ vlvIndex_init(struct vlvIndex* p, backend *be, struct vlvSearch* pSearch, const
p->vlv_search= pSearch;
/* Convert the textual sort specification into a keylist structure */
- ldap_create_sort_keylist(&(p->vlv_sortkey),p->vlv_sortspec);
+ internal_ldap_create_sort_keylist(&(p->vlv_sortkey),p->vlv_sortspec);
{
/*
* For each sort attribute find the appropriate syntax plugin,
@@ -938,3 +938,23 @@ vlv_isvlv(char *filename)
return 1;
return 0;
}
+
+void
+internal_ldap_free_sort_keylist(LDAPsortkey **sortKeyList)
+{
+#if defined(USE_OPENLDAP)
+ ldap_free_sort_keylist((LDAPSortKey **)sortKeyList);
+#else
+ ldap_free_sort_keylist(sortKeyList);
+#endif
+}
+
+int
+internal_ldap_create_sort_keylist(LDAPsortkey ***sortKeyList, const char *string_rep)
+{
+#if defined(USE_OPENLDAP)
+ return ldap_create_sort_keylist((LDAPSortKey ***)sortKeyList, (char *)string_rep);
+#else
+ return ldap_create_sort_keylist(sortKeyList, string_rep);
+#endif
+}
diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.h b/ldap/servers/slapd/back-ldbm/vlv_srch.h
index 71d8f27a..e32cf88b 100644
--- a/ldap/servers/slapd/back-ldbm/vlv_srch.h
+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.h
@@ -55,6 +55,17 @@ extern char* const type_vlvFilename;
extern char* const type_vlvEnabled;
extern char* const type_vlvUses;
+#if defined(USE_OPENLDAP)
+typedef struct LDAPsortkey { /* structure for a sort-key */
+ char * sk_attrtype;
+ char * sk_matchruleoid;
+ int sk_reverseorder;
+} LDAPsortkey;
+#endif
+
+void internal_ldap_free_sort_keylist(LDAPsortkey **sortKeyList);
+int internal_ldap_create_sort_keylist(LDAPsortkey ***sortKeyList, const char *string_rep);
+
/*
* This structure is the internal representation of a VLV Search.
*/
diff --git a/ldap/servers/slapd/charray.c b/ldap/servers/slapd/charray.c
index e57d9099..6ab492e1 100644
--- a/ldap/servers/slapd/charray.c
+++ b/ldap/servers/slapd/charray.c
@@ -320,9 +320,9 @@ charray_dup( char **a )
}
char **
-str2charray( char *str, char *brkstr )
+slapi_str2charray( char *str, char *brkstr )
{
- return( str2charray_ext( str, brkstr, 1 ));
+ return( slapi_str2charray_ext( str, brkstr, 1 ));
}
/*
@@ -330,7 +330,7 @@ str2charray( char *str, char *brkstr )
* duplicate values into the array.
*/
char **
-str2charray_ext( char *str, char *brkstr, int allow_dups )
+slapi_str2charray_ext( char *str, char *brkstr, int allow_dups )
{
char **res;
char *s;
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index e777d35b..8b1e2e5a 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -1465,6 +1465,48 @@ struct Conn_private
size_t c_buffer_offset; /* offset to the location of new data in the buffer */
};
+#if defined(USE_OPENLDAP)
+/* Copy up to bytes_to_read bytes from b into return_buffer.
+ * Returns a count of bytes copied (always >= 0).
+ */
+ber_slen_t
+openldap_read_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+ Connection *conn = NULL;
+ /* copy up to bytes_to_read bytes into the caller's buffer, return the number of bytes copied */
+ ber_slen_t bytes_to_copy = 0;
+ char *readbuf; /* buffer to "read" from */
+ size_t max; /* number of bytes currently stored in the buffer */
+ size_t offset; /* offset to the location of new data in the buffer */
+
+ PR_ASSERT(sbiod);
+ PR_ASSERT(sbiod->sbiod_pvt);
+
+ conn = (Connection *)sbiod->sbiod_pvt;
+
+ PR_ASSERT(conn->c_private->c_buffer);
+
+ readbuf = conn->c_private->c_buffer;
+ max = conn->c_private->c_buffer_bytes;
+ offset = conn->c_private->c_buffer_offset;
+
+ if (len <= (max - offset)) {
+ bytes_to_copy = len; /* we have enough buffered data */
+ } else {
+ bytes_to_copy = max - offset; /* just return what we have */
+ }
+
+ if (bytes_to_copy <= 0) {
+ bytes_to_copy = 0; /* never return a negative result */
+ } else {
+ /* copy buffered data into output buf */
+ SAFEMEMCPY(buf, readbuf + offset, bytes_to_copy);
+ conn->c_private->c_buffer_offset += bytes_to_copy;
+ }
+ return bytes_to_copy;
+}
+#endif
+
int
connection_new_private(Connection *conn)
{
@@ -1640,14 +1682,29 @@ get_next_from_buffer( void *buffer, size_t buffer_size, ber_len_t *lenp,
ber_len_t bytes_scanned = 0;
*lenp = 0;
+#if defined(USE_OPENLDAP)
+ *tagp = ber_get_next( conn->c_sb, &bytes_scanned, ber );
+#else
*tagp = ber_get_next_buffer_ext( buffer, buffer_size, lenp, ber,
&bytes_scanned, conn->c_sb );
- if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned)
+#endif
+ /* openldap ber_get_next doesn't return partial bytes_scanned if it hasn't
+ read a whole pdu - so we have to check the errno for the
+ "would block" condition meaning openldap needs more data to read */
+ if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned &&
+ !SLAPD_SYSTEM_WOULD_BLOCK_ERROR(errno))
{
if (LBER_OVERFLOW == *tagp)
{
err = SLAPD_DISCONNECT_BER_TOO_BIG;
}
+ else if (errno == ERANGE)
+ {
+ /* openldap does not differentiate between length == 0
+ and length > max - all we know is that there was a
+ problem with the length - assume too big */
+ err = SLAPD_DISCONNECT_BER_TOO_BIG;
+ }
else
{
err = SLAPD_DISCONNECT_BAD_BER_TAG;
@@ -1664,8 +1721,13 @@ get_next_from_buffer( void *buffer, size_t buffer_size, ber_len_t *lenp,
return -1;
}
+ /* openldap_read_function will advance c_buffer_offset */
+#if !defined(USE_OPENLDAP)
/* success, or need to wait for more data */
+ /* if openldap could not read a whole pdu, bytes_scanned will be zero -
+ it does not return partial results */
conn->c_private->c_buffer_offset += bytes_scanned;
+#endif
return 0;
}
diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c
index 3a0a86ce..29c6f8e7 100644
--- a/ldap/servers/slapd/conntable.c
+++ b/ldap/servers/slapd/conntable.c
@@ -67,10 +67,17 @@ connection_table_new(int table_size)
/* DBDB---move this out of here once everything works */
ct->c[i].c_sb = ber_sockbuf_alloc();
invalid_socket = SLAPD_INVALID_SOCKET;
- ber_sockbuf_set_option( ct->c[i].c_sb, LBER_SOCKBUF_OPT_DESC, &invalid_socket );
ct->c[i].c_sd = SLAPD_INVALID_SOCKET;
+#if defined(USE_OPENLDAP)
+ ber_sockbuf_ctrl( ct->c[i].c_sb, LBER_SB_OPT_SET_FD, &invalid_socket );
+ ber_sockbuf_ctrl( ct->c[i].c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &maxbersize );
+#else
+ ber_sockbuf_set_option( ct->c[i].c_sb, LBER_SOCKBUF_OPT_DESC, &invalid_socket );
+ /* openldap by default does not use readahead - the implementation is
+ via a sockbuf_io layer */
ber_sockbuf_set_option( ct->c[i].c_sb, LBER_SOCKBUF_OPT_NO_READ_AHEAD, LBER_OPT_ON );
ber_sockbuf_set_option( ct->c[i].c_sb, LBER_SOCKBUF_OPT_MAX_INCOMING_SIZE, &maxbersize );
+#endif /* !USE_OPENLDAP */
#ifndef _WIN32
/* all connections start out invalid */
ct->fd[i].fd = SLAPD_INVALID_SOCKET;
diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c
index aadf201b..f187f8d0 100644
--- a/ldap/servers/slapd/control.c
+++ b/ldap/servers/slapd/control.c
@@ -200,7 +200,7 @@ get_ldapmessage_controls_ext(
{
LDAPControl **ctrls, *new;
ber_tag_t tag;
- ber_len_t len;
+ ber_len_t len = -1;
int rc, maxcontrols, curcontrols;
char *last;
int managedsait, pwpolicy_ctrl;
@@ -277,6 +277,7 @@ get_ldapmessage_controls_ext(
for ( tag = ber_first_element( ber, &len, &last );
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
tag = ber_next_element( ber, &len, last ) ) {
+ len = -1; /* reset */
if ( curcontrols >= maxcontrols - 1 ) {
#define CONTROL_GRABSIZE 6
maxcontrols += CONTROL_GRABSIZE;
@@ -301,6 +302,7 @@ get_ldapmessage_controls_ext(
/* absent is synonomous with FALSE */
new->ldctl_iscritical = 0;
}
+ len = -1; /* reset */
/* if we are ignoring criticality, treat as FALSE */
if (ignore_criticality) {
new->ldctl_iscritical = 0;
@@ -345,9 +347,10 @@ get_ldapmessage_controls_ext(
(new->ldctl_value).bv_val = NULL;
(new->ldctl_value).bv_len = 0;
}
+ len = -1; /* reset for next loop iter */
}
- if ( tag == LBER_ERROR ) {
+ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
goto free_and_return;
}
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index 760cbb3f..59ae3a03 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -128,6 +128,8 @@ static int readsignalpipe = SLAPD_INVALID_SOCKET;
#define FDS_SIGNAL_PIPE 0
+
+
static int get_configured_connection_table_size();
#ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS
static void get_loopback_by_addr( void );
@@ -1652,104 +1654,17 @@ slapd_poll( void *handle, int output )
return rc;
}
-/* The following 4 functions each read or write count bytes from or to
- * a socket handle. If all goes well, they return the same count;
- * otherwise they return -1 and PR_GetError() explains the problem.
- * Revision: handle changed to struct lextiof_socket_private * and first
- * argument which used to be handle is now ignored.
- */
-int
-read_function( int ignore, void *buffer, int count, struct lextiof_socket_private *handle )
-{
- int gotbytes = 0;
- int bytes;
- int ioblock_timeout = config_get_ioblocktimeout();
- PRIntervalTime pr_timeout = PR_MillisecondsToInterval(ioblock_timeout);
- int fd = PR_FileDesc2NativeHandle((PRFileDesc *)handle);
-
- if (handle == SLAPD_INVALID_SOCKET) {
- PR_SetError(PR_NOT_SOCKET_ERROR, EBADF);
- } else {
- while (1) {
- bytes = PR_Recv( (PRFileDesc *)handle, (char *)buffer + gotbytes,
- count - gotbytes, 0, pr_timeout );
- if (bytes > 0) {
- gotbytes += bytes;
- } else if (bytes < 0) {
- PRErrorCode prerr = PR_GetError();
-
-#ifdef _WIN32
- /* we need to do this because on NT, once an I/O
- times out on an NSPR socket, that socket must
- be closed before any other I/O can happen in
- this thread.
- */
- if (prerr == PR_IO_TIMEOUT_ERROR) {
- Connection *conn = connection_table_get_connection_from_fd(the_connection_table,(PRFileDesc *)handle);
- if (conn == NULL)
- return -1;
-
- disconnect_server (conn, conn->c_connid, -1, SLAPD_DISCONNECT_NTSSL_TIMEOUT, 0);
- /* Disconnect_server just tells the poll thread that the
- * socket should be closed. We'll sleep 2 seconds here to
- * to make sure that the poll thread has time to run
- * and close this socket. */
- DS_Sleep(PR_SecondsToInterval(2));
-
- LDAPDebug(LDAP_DEBUG_CONNS, "PR_Recv(%d) "
- SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
- fd, prerr, slapd_pr_strerror(prerr));
-
- return -1;
- }
-#endif
-
- LDAPDebug(LDAP_DEBUG_CONNS,
- "PR_Recv(%d) error %d (%s)\n",
- fd, prerr, slapd_pr_strerror(prerr));
- if ( !SLAPD_PR_WOULD_BLOCK_ERROR(prerr) ) {
- LDAPDebug(LDAP_DEBUG_ANY,
- "PR_Recv(%d) error %d (%s)\n",
- fd, prerr, slapd_pr_strerror(prerr));
- break; /* fatal error */
- }
- } else if (bytes == 0) { /* PR_Recv says bytes == 0 means conn closed */
- PRErrorCode prerr = PR_GetError();
- LDAPDebug(LDAP_DEBUG_CONNS,
- "PR_Recv(%d) - 0 (EOF) %d:%s\n", /* disconnected */
- fd, prerr, slapd_pr_strerror(prerr));
- PR_SetError(PR_PIPE_ERROR, EPIPE);
- break;
- } else if (gotbytes < count) {
- LDAPDebug(LDAP_DEBUG_CONNS,
- "PR_Recv(%d) received only %d bytes (expected %d bytes) - 0 (EOF)\n", /* disconnected */
- fd, gotbytes, count);
- PR_SetError(PR_PIPE_ERROR, EPIPE);
- break;
- }
- if (gotbytes == count) { /* success */
- return count;
- } else if (gotbytes > count) { /* too many bytes */
- LDAPDebug(LDAP_DEBUG_ANY,
- "PR_Recv(%d) overflow - received %d bytes (expected %d bytes) - error\n",
- fd, gotbytes, count);
- PR_SetError(PR_BUFFER_OVERFLOW_ERROR, EMSGSIZE);
- break;
- } else if (slapd_poll(handle, SLAPD_POLLIN) < 0) { /* error */
- break;
- }
- }
- }
- return -1;
-}
-
-
/*
- * Revision: handle changed to struct lextiof_socket_private * and first
- * argument which used to be handle is now ignored.
+ * Revision: handle changed to void * and first
+ * argument which used to be integer system fd is now ignored.
*/
-int
+#if defined(USE_OPENLDAP)
+static int
+write_function( int ignore, void *buffer, int count, void *handle )
+#else
+static int
write_function( int ignore, const void *buffer, int count, struct lextiof_socket_private *handle )
+#endif
{
int sentbytes = 0;
int bytes;
@@ -1805,6 +1720,63 @@ write_function( int ignore, const void *buffer, int count, struct lextiof_socket
return -1;
}
+#if defined(USE_OPENLDAP)
+/* The argument is a pointer to the socket descriptor */
+static int
+openldap_io_setup(Sockbuf_IO_Desc *sbiod, void *arg)
+{
+ PR_ASSERT(sbiod);
+
+ if (arg != NULL) {
+ sbiod->sbiod_pvt = arg;
+ }
+ return 0;
+}
+
+static ber_slen_t
+openldap_write_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+ Connection *conn = NULL;
+ PRFileDesc *fd = NULL;
+
+ PR_ASSERT(sbiod);
+ PR_ASSERT(sbiod->sbiod_pvt);
+
+ conn = (Connection *)sbiod->sbiod_pvt;
+
+ PR_ASSERT(conn->c_prfd);
+
+ fd = (PRFileDesc *)conn->c_prfd;
+
+ PR_ASSERT(fd != SLAPD_INVALID_SOCKET);
+
+ return write_function(0, buf, len, fd);
+}
+
+static int
+openldap_io_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
+{
+ PR_ASSERT(0); /* not sure if this is needed */
+ return -1;
+}
+
+static int
+openldap_io_close(Sockbuf_IO_Desc *sbiod)
+{
+ return 0; /* closing done in connection_cleanup() */
+}
+
+static Sockbuf_IO openldap_sockbuf_io = {
+ openldap_io_setup, /* sbi_setup */
+ NULL, /* sbi_remove */
+ openldap_io_ctrl, /* sbi_ctrl */
+ openldap_read_function, /* sbi_read */ /* see connection.c */
+ openldap_write_function, /* sbi_write */
+ openldap_io_close /* sbi_close */
+};
+
+#endif /* USE_OPENLDAP */
+
int connection_type = -1; /* The type number assigned by the Factory for 'Connection' */
@@ -2145,11 +2117,15 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, i
/* fds[ns].out_flags = 0; */
#endif
+#if defined(USE_OPENLDAP)
+ ber_sockbuf_add_io( conn->c_sb, &openldap_sockbuf_io,
+ LBER_SBIOD_LEVEL_PROVIDER, conn );
+#else /* !USE_OPENLDAP */
{
struct lber_x_ext_io_fns func_pointers;
memset(&func_pointers, 0, sizeof(func_pointers));
func_pointers.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
- func_pointers.lbextiofn_read = read_function;
+ func_pointers.lbextiofn_read = NULL; /* see connection_read_function */
func_pointers.lbextiofn_write = write_function;
func_pointers.lbextiofn_writev = NULL;
#ifdef _WIN32
@@ -2160,6 +2136,7 @@ handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, i
ber_sockbuf_set_option( conn->c_sb,
LBER_SOCKBUF_OPT_EXT_IO_FNS, &func_pointers);
}
+#endif /* !USE_OPENLDAP */
if( secure && config_get_SSLclientAuth() != SLAPD_SSLCLIENTAUTH_OFF ) {
/* Prepare to handle the client's certificate (if any): */
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
index 04a1b356..63abaa6f 100644
--- a/ldap/servers/slapd/dse.c
+++ b/ldap/servers/slapd/dse.c
@@ -1204,9 +1204,9 @@ entry_dn_cmp( caddr_t d1, caddr_t d2 )
retval = len1 - len2;
if (dnlist1)
- ldap_value_free(dnlist1);
+ slapi_ldap_value_free(dnlist1);
if (dnlist2)
- ldap_value_free(dnlist2);
+ slapi_ldap_value_free(dnlist2);
}
}
/* else entries are equal if dns are equal */
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 72b3e340..fea08814 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -196,12 +196,17 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
{
Slapi_Attr **a;
char *valuecharptr=NULL;
+#if defined(USE_OPENLDAP)
+ ber_len_t valuelen;
+#else
int valuelen;
+#endif
int value_state= VALUE_NOTFOUND;
int attr_state= ATTRIBUTE_NOTFOUND;
int maxvals;
int del_maxvals;
char *type;
+ int freetype = 0;
if ( *s == '\n' || *s == '\0' ) {
break;
@@ -212,6 +217,11 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
"<= str2entry_fast NULL (parse_line)\n", 0, 0, 0 );
continue;
}
+#if defined(USE_OPENLDAP)
+ /* openldap always mallocs the type and value arguments to ldap_parse_line */
+ retmalloc = 1;
+ freetype = 1;
+#endif
/*
* Extract the attribute and value CSNs from the attribute type.
@@ -228,7 +238,8 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
{
/* ignore deleted values and attributes */
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
/* Ignore CSNs */
@@ -240,7 +251,8 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
*/
if((ptype==NULL)||(strcasecmp(type,ptype) != 0))
{
- ptype=type;
+ slapi_ch_free_string(&ptype);
+ ptype=slapi_ch_strdup(type);
nvals = 0;
maxvals = 0;
del_nvals = 0;
@@ -259,11 +271,13 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
escape_string( valuecharptr, ebuf ), 0 );
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
@@ -281,7 +295,8 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
attr_syntax_read_lock();
}
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
@@ -296,7 +311,7 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
Slapi_Value *value= value_new(NULL,CSN_TYPE_NONE,NULL);
slapi_value_set( value, valuecharptr, valuelen );
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
value->v_csnset= valuecsnset;
valuecsnset= NULL;
if(a==NULL)
@@ -308,6 +323,7 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
{
LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous attribute values for %s\n", type, 0, 0);
PR_ASSERT(0);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
break;
@@ -316,17 +332,20 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
{
LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type, 0, 0);
PR_ASSERT(0);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
break;
case ATTRIBUTE_NOTFOUND:
LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: Error. Non-contiguous deleted attribute values for %s\n", type, 0, 0);
PR_ASSERT(0);
+ if (freetype) slapi_ch_free_string(&type);
continue;
/* break; ??? */
}
}
+ if (freetype) slapi_ch_free_string(&type); /* don't need type anymore */
{
const CSN *distinguishedcsn= csnset_get_csn_of_type(value->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
if(distinguishedcsn!=NULL)
@@ -367,6 +386,7 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
csnset_free(&valuecsnset);
attr_val_cnt++;
}
+ slapi_ch_free_string(&ptype);
if ( attr_val_cnt >= ENTRY_MAX_ATTRIBUTE_VALUE_COUNT )
{
LDAPDebug( LDAP_DEBUG_ANY,
@@ -597,7 +617,12 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
CSNSet *valuecsnset= NULL;
int value_state= VALUE_NOTFOUND;
int attr_state= VALUE_NOTFOUND;
- int valuelen;
+ int freetype = 0;
+#if defined(USE_OPENLDAP)
+ ber_len_t valuelen;
+#else
+ int valuelen;
+#endif
if ( *s == '\n' || *s == '\0' ) {
break;
@@ -608,7 +633,11 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
"<= slapi_str2entry NULL (parse_line)\n", 0, 0, 0 );
continue;
}
-
+#if defined(USE_OPENLDAP)
+ /* openldap always mallocs type and value */
+ retmalloc = 1;
+ freetype = 1;
+#endif
/*
* Extract the attribute and value CSNs from the attribute type.
*/
@@ -624,7 +653,8 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
{
/* ignore deleted values and attributes */
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
/* Ignore CSNs */
@@ -640,12 +670,14 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
escape_string( slapi_entry_get_dn_const(e), ebuf ),
escape_string( valuecharptr, ebuf ), 0 );
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
@@ -660,7 +692,8 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
slapi_entry_set_uniqueid (e, slapi_ch_strdup(valuecharptr));
}
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
continue;
}
@@ -702,6 +735,8 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if (0 != entry_attrs_new(&ea))
{
/* Something very bad happened */
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
return NULL;
}
for ( i = 0; i < nattrs; i++ )
@@ -755,6 +790,8 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
"<= slapi_str2entry NULL (slapi_attr_type2plugin)\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
goto free_and_return;
}
/* Get the comparison function for later use */
@@ -781,11 +818,12 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
nattrs++;
}
+ if (freetype) slapi_ch_free_string(&type);
sa = prev_attr; /* For readability */
value= value_new(NULL,CSN_TYPE_NONE,NULL);
slapi_value_set( value, valuecharptr, valuelen );
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
value->v_csnset= valuecsnset;
valuecsnset= NULL;
{
@@ -1228,12 +1266,12 @@ entry2str_internal_put_value( const char *attrtype, const CSN *attrcsn, CSNType
{
type= attrtype;
}
+ bvp = slapi_value_get_berval(v);
if (entry2str_ctrl & SLAPI_DUMP_NOWRAP)
options |= LDIF_OPT_NOWRAP;
if (entry2str_ctrl & SLAPI_DUMP_MINIMAL_ENCODING)
options |= LDIF_OPT_MINIMAL_ENCODING;
- bvp = slapi_value_get_berval(v);
- ldif_put_type_and_value_with_options( ecur, (char*)type, bvp->bv_val, bvp->bv_len, options );
+ slapi_ldif_put_type_and_value_with_options( ecur, type, bvp->bv_val, bvp->bv_len, options );
}
static void
@@ -2432,12 +2470,12 @@ slapi_entry_rdn_values_present( const Slapi_Entry *e )
}
}
}
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
} else {
rc = 0; /* Failure: the RDN seems invalid */
}
- ldap_value_free( dns );
+ slapi_ldap_value_free( dns );
}
else
{
@@ -2470,16 +2508,16 @@ slapi_entry_add_rdn_values( Slapi_Entry *e )
return( LDAP_INVALID_DN_SYNTAX );
}
if ( (rdns = ldap_explode_rdn( dns[0], 0 )) == NULL ) {
- ldap_value_free( dns );
+ slapi_ldap_value_free( dns );
return( LDAP_INVALID_DN_SYNTAX );
}
- ldap_value_free( dns );
+ slapi_ldap_value_free( dns );
for ( i = 0; rdns[i] != NULL && rc == LDAP_SUCCESS; i++ ) {
struct ava ava;
char *type;
if ( rdn2ava( rdns[i], &ava ) != 0 ) {
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
return( LDAP_INVALID_DN_SYNTAX );
}
@@ -2528,7 +2566,7 @@ slapi_entry_add_rdn_values( Slapi_Entry *e )
slapi_ch_free( (void **)&type );
}
- ldap_value_free( rdns );
+ slapi_ldap_value_free( rdns );
return( rc );
}
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
index fb4ed3a0..3eb1d0ad 100644
--- a/ldap/servers/slapd/fe.h
+++ b/ldap/servers/slapd/fe.h
@@ -175,8 +175,6 @@ void slapd_daemon( daemon_ports_t *ports );
void daemon_register_connection();
int slapd_listenhost2addr( const char *listenhost, PRNetAddr ***addr );
int daemon_register_reslimits( void );
-int read_function(int ignore, void *buffer, int count, struct lextiof_socket_private *handle );
-int write_function(int ignore, const void *buffer, int count, struct lextiof_socket_private *handle );
PRFileDesc * get_ssl_listener_fd();
int configure_pr_socket( PRFileDesc **pr_socket, int secure, int local );
void configure_ns_socket( int * ns );
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index beec7d5c..0439007b 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -1728,7 +1728,11 @@ search_easter_egg( Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *entr
{
static int twiddle= -1;
char *type, *value, *copy;
+#if defined(USE_OPENLDAP)
+ ber_len_t vlen;
+#else
int vlen;
+#endif
struct berval bv;
struct berval *bvals[2];
if (twiddle < 0) {
diff --git a/ldap/servers/slapd/filter.c b/ldap/servers/slapd/filter.c
index a3ec29c9..b3e96b4a 100644
--- a/ldap/servers/slapd/filter.c
+++ b/ldap/servers/slapd/filter.c
@@ -418,7 +418,7 @@ get_filter_list( Connection *conn, BerElement *ber,
struct slapi_filter **new;
int err;
ber_tag_t tag;
- ber_len_t len;
+ ber_len_t len = -1;
char *last;
LDAPDebug( LDAP_DEBUG_FILTER, "=> get_filter_list\n", 0, 0, 0 );
@@ -447,10 +447,16 @@ get_filter_list( Connection *conn, BerElement *ber,
slapi_ch_free((void**)&ftmp );
}
new = &(*new)->f_next;
+ len = -1;
}
*new = NULL;
- if ( tag == LBER_ERROR && *fstr != NULL ) {
+ /* openldap does not return LBER_END_OF_SEQORSET -
+ so check for len == -1 - openldap ber_next_element will not set
+ len if it has reached the end, and -1 is not a valid value
+ for a real len */
+ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) && (*fstr != NULL) ) {
+ LDAPDebug( LDAP_DEBUG_ANY, " error parsing filter list\n", 0, 0, 0 );
slapi_ch_free((void**)fstr );
}
@@ -467,7 +473,7 @@ get_substring_filter(
)
{
ber_tag_t tag, rc;
- ber_len_t len;
+ ber_len_t len = -1;
char *val, *last, *type = NULL;
char ebuf[BUFSIZ];
@@ -489,6 +495,7 @@ get_substring_filter(
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
tag = ber_next_element( ber, &len, last ) )
{
+ len = -1; /* reset - not used in loop */
val = NULL;
rc = ber_scanf( ber, "a", &val );
if ( rc == LBER_ERROR ) {
@@ -547,7 +554,8 @@ get_substring_filter(
}
}
- if ( tag == LBER_ERROR ) {
+ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
+ LDAPDebug( LDAP_DEBUG_ANY, " error reading substring filter\n", 0, 0, 0 );
return( LDAP_PROTOCOL_ERROR );
}
if ( f->f_sub_initial == NULL && f->f_sub_any == NULL &&
@@ -571,7 +579,7 @@ get_extensible_filter( BerElement *ber, mr_filter_t* mrf )
{
int gotelem, gotoid, gotvalue;
ber_tag_t tag;
- ber_len_t len;
+ ber_len_t len = -1;
char *last;
int rc = LDAP_SUCCESS;
@@ -589,6 +597,7 @@ get_extensible_filter( BerElement *ber, mr_filter_t* mrf )
*
* where either oid or type is required.
*/
+ len = -1; /* reset - not used in loop */
switch ( tag ) {
case LDAP_TAG_MRA_OID:
if ( gotelem != 0 ) {
@@ -645,7 +654,7 @@ get_extensible_filter( BerElement *ber, mr_filter_t* mrf )
}
}
- if ( tag == LBER_ERROR ) {
+ if ( (tag != LBER_ERROR) && (len != -1) ) {
goto parsing_error;
}
diff --git a/ldap/servers/slapd/filterentry.c b/ldap/servers/slapd/filterentry.c
index e9df0949..f5666763 100644
--- a/ldap/servers/slapd/filterentry.c
+++ b/ldap/servers/slapd/filterentry.c
@@ -444,10 +444,10 @@ dn2attrs(const char *dn)
slapi_ch_free_string( &type );
}
}
- ldap_value_free (avas);
+ slapi_ldap_value_free (avas);
}
}
- ldap_value_free (rdns);
+ slapi_ldap_value_free (rdns);
}
return dnAttrs;
}
diff --git a/ldap/servers/slapd/getfilelist.c b/ldap/servers/slapd/getfilelist.c
index b2ef6e21..ac79430f 100644
--- a/ldap/servers/slapd/getfilelist.c
+++ b/ldap/servers/slapd/getfilelist.c
@@ -130,7 +130,7 @@ matches(const char *filename, const char *pattern)
return 1; /* null pattern matches everything */
/* Compile the pattern */
- re = slapi_re_comp( (char *)pattern, &error );
+ re = slapi_re_comp( pattern, &error );
if (re) {
/* Matches the compiled pattern against the filename */
match = slapi_re_exec( re, filename, -1 /* no time limit */ );
diff --git a/ldap/servers/slapd/globals.c b/ldap/servers/slapd/globals.c
index e49aa889..91c21ed6 100644
--- a/ldap/servers/slapd/globals.c
+++ b/ldap/servers/slapd/globals.c
@@ -49,7 +49,6 @@
#include "ldap.h"
#include <sslproto.h> /* cipher suite names */
-#include <ldap_ssl.h>
#undef OFF
#undef LITTLE_ENDIAN
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
new file mode 100644
index 00000000..4ea56143
--- /dev/null
+++ b/ldap/servers/slapd/ldaputil.c
@@ -0,0 +1,1529 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2005 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* ldaputil.c -- LDAP utility functions and wrappers */
+#ifdef _WIN32
+#include <direct.h> /* for getcwd */
+#else
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <pwd.h>
+#endif
+#include <libgen.h>
+#include <pk11func.h>
+#include "slap.h"
+#include "prtime.h"
+#include "prinrval.h"
+#include "snmp_collator.h"
+#if !defined(USE_OPENLDAP)
+#include <ldap_ssl.h>
+#include <ldappr.h>
+#endif
+
+#ifdef MEMPOOL_EXPERIMENTAL
+void _free_wrapper(void *ptr)
+{
+ slapi_ch_free(&ptr);
+}
+#endif
+
+/*
+ * Function: slapi_ldap_unbind()
+ * Purpose: release an LDAP session obtained from a call to slapi_ldap_init().
+ */
+void
+slapi_ldap_unbind( LDAP *ld )
+{
+ if ( ld != NULL ) {
+ ldap_unbind_ext( ld, NULL, NULL );
+ }
+}
+
+const char *
+slapi_urlparse_err2string( int err )
+{
+ const char *s="internal error";
+
+ switch( err ) {
+ case 0:
+ s = "no error";
+ break;
+ case LDAP_URL_ERR_BADSCOPE:
+ s = "invalid search scope";
+ break;
+ case LDAP_URL_ERR_MEM:
+ s = "unable to allocate memory";
+ break;
+ case LDAP_URL_ERR_PARAM:
+ s = "bad parameter to an LDAP URL function";
+ break;
+#if defined(USE_OPENLDAP)
+ case LDAP_URL_ERR_BADSCHEME:
+ s = "does not begin with ldap://, ldaps://, or ldapi://";
+ break;
+ case LDAP_URL_ERR_BADENCLOSURE:
+ s = "missing trailing '>' in enclosure";
+ break;
+ case LDAP_URL_ERR_BADURL:
+ s = "not a valid LDAP URL";
+ break;
+ case LDAP_URL_ERR_BADHOST:
+ s = "hostname part of url is not valid or not given";
+ break;
+ case LDAP_URL_ERR_BADATTRS:
+ s = "attribute list not formatted correctly or missing";
+ break;
+ case LDAP_URL_ERR_BADFILTER:
+ s = "search filter not correct";
+ break;
+ case LDAP_URL_ERR_BADEXTS:
+ s = "extensions not specified correctly";
+ break;
+#else /* !USE_OPENLDAP */
+ case LDAP_URL_ERR_NOTLDAP:
+ s = "missing ldap:// or ldaps:// or ldapi://";
+ break;
+ case LDAP_URL_ERR_NODN:
+ s = "missing suffix";
+ break;
+#endif
+ }
+
+ return( s );
+}
+
+/* there are various differences among url parsers - directory server
+ needs the ability to parse partial URLs - those with no dn - and
+ needs to be able to tell if it is a secure url (ldaps) or not */
+int
+slapi_ldap_url_parse(const char *url, LDAPURLDesc **ludpp, int require_dn, int *secure)
+{
+ PR_ASSERT(url);
+ PR_ASSERT(ludpp);
+ int rc;
+
+ if (secure) {
+ *secure = 0;
+ }
+#if defined(HAVE_LDAP_URL_PARSE_NO_DEFAULTS)
+ rc = ldap_url_parse_no_defaults(url, ludpp, require_dn);
+ if (!rc && *ludpp && secure) {
+ *secure = (*ludpp)->lud_options & LDAP_URL_OPT_SECURE;
+ }
+#else /* openldap */
+#if defined(HAVE_LDAP_URL_PARSE_EXT)
+ rc = ldap_url_parse_ext(url, ludpp, require_dn ? LDAP_PVT_URL_PARSE_NONE : LDAP_PVT_URL_PARSE_NOEMPTY_DN);
+#else
+ rc = ldap_url_parse(url, ludpp);
+ if (rc || !*ludpp || !require_dn) { /* failed - see if failure was due to missing dn */
+ size_t len = strlen(url);
+ /* assume the url is just scheme://host:port[/] - add the empty string
+ as the DN (adding a trailing / first if needed) and try to parse
+ again
+ */
+ char *urlcopy = slapi_ch_smprintf("%s%s%s", url, (url[len-1] == '/' ? "" : "/"), "");
+ rc = ldap_url_parse(urlcopy, ludpp);
+ slapi_ch_free_string(&urlcopy);
+ if (0 == rc) { /* only problem was the DN - free it */
+ slapi_ch_free_string(&((*ludpp)->lud_dn));
+ }
+ }
+#endif
+ if (!rc && *ludpp && secure) {
+ *secure = (*ludpp)->lud_scheme && !strcmp((*ludpp)->lud_scheme, "ldaps");
+ }
+#endif /* openldap */
+
+ return rc;
+}
+
+#include <sasl.h>
+
+int
+slapi_ldap_get_lderrno(LDAP *ld, char **m, char **s)
+{
+ int rc = LDAP_SUCCESS;
+
+#if defined(USE_OPENLDAP)
+ ldap_get_option(ld, LDAP_OPT_RESULT_CODE, &rc);
+ if (m) {
+ ldap_get_option(ld, LDAP_OPT_MATCHED_DN, m);
+ }
+ if (s) {
+#ifdef LDAP_OPT_DIAGNOSTIC_MESSAGE
+ ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, s);
+#else
+ ldap_get_option(ld, LDAP_OPT_ERROR_STRING, s);
+#endif
+ }
+#else /* !USE_OPENLDAP */
+ rc = ldap_get_lderrno( ld, m, s );
+#endif
+ return rc;
+}
+
+void
+slapi_ldif_put_type_and_value_with_options( char **out, const char *t, const char *val, int vlen, unsigned long options )
+{
+#if defined(USE_OPENLDAP)
+ /* openldap always wraps and always does conservative base64 encoding
+ we unwrap here, but clients will have to do their own base64 decode */
+ int type = LDIF_PUT_VALUE;
+ char *save = *out;
+
+ if (options & LDIF_OPT_VALUE_IS_URL) {
+ type = LDIF_PUT_URL;
+ }
+ ldif_sput( out, type, t, val, vlen );
+ if (options & LDIF_OPT_NOWRAP) {
+ /* modify out in place, stripping out continuation lines */
+ char *src = save;
+ char *dest = save;
+ for (; src && *src && (src != *out); ++src) {
+ if (!strncmp(src, "\n ", 2)) {
+ src += 2; /* skip continuation */
+ }
+ *dest++ = *src;
+ }
+ *dest = '\n';
+ }
+#else
+ ldif_put_type_and_value_with_options( out, (char *)t, (char *)val, vlen, options );
+#endif
+}
+
+void
+slapi_ldap_value_free( char **vals )
+{
+#if defined(USE_OPENLDAP)
+ slapi_ch_array_free(vals);
+#else
+ ldap_value_free(vals);
+#endif
+}
+
+int
+slapi_ldap_count_values( char **vals )
+{
+#if defined(USE_OPENLDAP)
+ return ldap_count_values_len((struct berval **)vals);
+#else
+ return ldap_count_values(vals);
+#endif
+}
+
+/*
+ Perform LDAP init and return an LDAP* handle. If ldapurl is given,
+ that is used as the basis for the protocol, host, port, and whether
+ to use starttls (given on the end as ldap://..../?????starttlsOID
+ If hostname is given, LDAP or LDAPS is assumed, and this will override
+ the hostname from the ldapurl, if any. If port is > 0, this is the
+ port number to use. It will override the port in the ldapurl, if any.
+ If no port is given in port or ldapurl, the default will be used based
+ on the secure setting (389 for ldap, 636 for ldaps, 389 for starttls)
+ secure takes 1 of 3 values - 0 means regular ldap, 1 means ldaps, 2
+ means regular ldap with starttls.
+ filename is the ldapi file name - if this is given, and no other options
+ are given, ldapi is assumed.
+ */
+/* util_sasl_path: the string argument for putenv.
+ It must be a global or a static */
+char util_sasl_path[MAXPATHLEN];
+
+LDAP *
+slapi_ldap_init_ext(
+ const char *ldapurl, /* full ldap url */
+ const char *hostname, /* can also use this to override
+ host in url */
+ int port, /* can also use this to override port in url */
+ int secure, /* 0 for ldap, 1 for ldaps, 2 for starttls -
+ override proto in url */
+ int shared, /* if true, LDAP* will be shared among multiple threads */
+ const char *filename /* for ldapi */
+)
+{
+ LDAPURLDesc *ludp = NULL;
+ LDAP *ld = NULL;
+ int rc = 0;
+ int secureurl = 0;
+
+ /* We need to provide a sasl path used for client connections, especially
+ if the server is not set up to be a sasl server - since mozldap provides
+ no way to override the default path programatically, we set the sasl
+ path to the environment variable SASL_PATH. */
+ char *configpluginpath = config_get_saslpath();
+ char *pluginpath = configpluginpath;
+ char *pp = NULL;
+
+ if (NULL == pluginpath || (*pluginpath == '\0')) {
+ slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_init_ext",
+ "configpluginpath == NULL\n");
+ if (!(pluginpath = getenv("SASL_PATH"))) {
+#if defined(LINUX) && defined(__LP64__)
+ pluginpath = "/usr/lib64/sasl2";
+#else
+ pluginpath = "/usr/lib/sasl2";
+#endif
+ }
+ }
+ if ('\0' == util_sasl_path[0] || /* first time */
+ NULL == (pp = strchr(util_sasl_path, '=')) || /* invalid arg for putenv */
+ (0 != strcmp(++pp, pluginpath)) /* sasl_path has been updated */ ) {
+ PR_snprintf(util_sasl_path, sizeof(util_sasl_path),
+ "SASL_PATH=%s", pluginpath);
+ slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_init_ext",
+ "putenv(%s)\n", util_sasl_path);
+ putenv(util_sasl_path);
+ }
+ slapi_ch_free_string(&configpluginpath);
+
+ /* if ldapurl is given, parse it */
+ if (ldapurl && ((rc = slapi_ldap_url_parse(ldapurl, &ludp, 0, &secureurl)) ||
+ !ludp)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "Could not parse given LDAP URL [%s] : error [%s]\n",
+ ldapurl ? ldapurl : "NULL",
+ slapi_urlparse_err2string(rc));
+ goto done;
+ }
+
+ /* use url host if no host given */
+ if (!hostname && ludp && ludp->lud_host) {
+ hostname = ludp->lud_host;
+ }
+
+ /* use url port if no port given */
+ if (!port && ludp && ludp->lud_port) {
+ port = ludp->lud_port;
+ }
+
+ /* use secure setting from url if none given */
+ if (!secure && ludp) {
+ if (secureurl) {
+ secure = 1;
+ } else if (0/* starttls option - not supported yet in LDAP URLs */) {
+ secure = 2;
+ }
+ }
+
+ /* ldap_url_parse doesn't yet handle ldapi */
+ /*
+ if (!filename && ludp && ludp->lud_file) {
+ filename = ludp->lud_file;
+ }
+ */
+
+#ifdef MEMPOOL_EXPERIMENTAL
+ {
+ /*
+ * slapi_ch_malloc functions need to be set to LDAP C SDK
+ */
+ struct ldap_memalloc_fns memalloc_fns;
+ memalloc_fns.ldapmem_malloc = (LDAP_MALLOC_CALLBACK *)slapi_ch_malloc;
+ memalloc_fns.ldapmem_calloc = (LDAP_CALLOC_CALLBACK *)slapi_ch_calloc;
+ memalloc_fns.ldapmem_realloc = (LDAP_REALLOC_CALLBACK *)slapi_ch_realloc;
+ memalloc_fns.ldapmem_free = (LDAP_FREE_CALLBACK *)_free_wrapper;
+ }
+ /*
+ * MEMPOOL_EXPERIMENTAL:
+ * These LDAP C SDK init function needs to be revisited.
+ * In ldap_init called via ldapssl_init and prldap_init initializes
+ * options and set default values including memalloc_fns, then it
+ * initializes as sasl client by calling sasl_client_init. In
+ * sasl_client_init, it creates mechlist using the malloc function
+ * available at the moment which could mismatch the malloc/free functions
+ * set later.
+ */
+#endif
+
+#if defined(USE_OPENLDAP)
+ if (ldapurl) {
+ rc = ldap_initialize(&ld, ldapurl);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "Could not initialize LDAP connection to [%s]: %d:%s\n",
+ ldapurl, rc, ldap_err2string(rc));
+ goto done;
+ }
+ } else {
+ char *makeurl = NULL;
+ if (filename) {
+ makeurl = slapi_ch_smprintf("ldapi://%s/", filename);
+ } else { /* host port */
+ makeurl = slapi_ch_smprintf("ldap%s://%s:%d/", (secure == 1 ? "s" : ""), hostname, port);
+ }
+ rc = ldap_initialize(&ld, makeurl);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "Could not initialize LDAP connection to [%s]: %d:%s\n",
+ makeurl, rc, ldap_err2string(rc));
+ slapi_ch_free_string(&makeurl);
+ goto done;
+ }
+ slapi_ch_free_string(&makeurl);
+ }
+#else /* !USE_OPENLDAP */
+ if (filename) {
+ /* ldapi in mozldap client is not yet supported */
+ } else if (secure == 1) {
+ ld = ldapssl_init(hostname, port, secure);
+ } else { /* regular ldap and/or starttls */
+ /*
+ * Leverage the libprldap layer to take care of all the NSPR
+ * integration.
+ * Note that ldapssl_init() uses libprldap implicitly.
+ */
+ ld = prldap_init(hostname, port, shared);
+ }
+#endif /* !USE_OPENLDAP */
+ /* Update snmp interaction table */
+ if (hostname) {
+ if (ld == NULL) {
+ set_snmp_interaction_row((char *)hostname, port, -1);
+ } else {
+ set_snmp_interaction_row((char *)hostname, port, 0);
+ }
+ }
+
+ if ((ld != NULL) && !filename) {
+ /*
+ * Set the outbound LDAP I/O timeout based on the server config.
+ */
+ int io_timeout_ms = config_get_outbound_ldap_io_timeout();
+ if (io_timeout_ms > 0) {
+#if defined(USE_OPENLDAP)
+ struct timeval tv;
+ tv.tv_sec = io_timeout_ms / 1000;
+ tv.tv_usec = (io_timeout_ms % 1000) * 1000;
+ if (LDAP_OPT_SUCCESS != ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set outbound I/O "
+ "timeout to %dms\n",
+ io_timeout_ms);
+ slapi_ldap_unbind(ld);
+ ld = NULL;
+ goto done;
+ }
+#else /* !USE_OPENLDAP */
+ if (prldap_set_session_option(ld, NULL, PRLDAP_OPT_IO_MAX_TIMEOUT,
+ io_timeout_ms) != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set outbound I/O "
+ "timeout to %dms\n",
+ io_timeout_ms);
+ slapi_ldap_unbind(ld);
+ ld = NULL;
+ goto done;
+ }
+#endif /* !USE_OPENLDAP */
+ }
+
+ /*
+ * Set SSL strength (server certificate validity checking).
+ */
+ if (secure > 0) {
+#if !defined(USE_OPENLDAP)
+ int ssl_strength = 0;
+#endif
+ LDAP *myld = NULL;
+
+ /* we can only use the set functions below with a real
+ LDAP* if it has already gone through ldapssl_init -
+ so, use NULL if using starttls */
+ if (secure == 1) {
+ myld = ld;
+ }
+
+ if (config_get_ssl_check_hostname()) {
+ /* check hostname against name in certificate */
+#if defined(USE_OPENLDAP)
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, "hard"))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set REQUIRE_CERT option to hard\n");
+ }
+#else /* !USE_OPENLDAP */
+ ssl_strength = LDAPSSL_AUTH_CNCHECK;
+#endif /* !USE_OPENLDAP */
+ } else {
+ /* verify certificate only */
+#if defined(USE_OPENLDAP)
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, "allow"))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set REQUIRE_CERT option to allow\n");
+ }
+#else /* !USE_OPENLDAP */
+ ssl_strength = LDAPSSL_AUTH_CERT;
+#endif /* !USE_OPENLDAP */
+ }
+
+#if defined(USE_OPENLDAP)
+#if defined(LDAP_OPT_X_TLS_PROTOCOL_MIN)
+ if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, LDAP_OPT_X_TLS_PROTOCOL_SSL3))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set minimum TLS protocol level to SSL3n");
+ }
+#endif /* LDAP_OPT_X_TLS_PROTOCOL_MIN */
+#else /* !USE_OPENLDAP */
+ if ((rc = ldapssl_set_strength(myld, ssl_strength)) ||
+ (rc = ldapssl_set_option(myld, SSL_ENABLE_SSL2, PR_FALSE)) ||
+ (rc = ldapssl_set_option(myld, SSL_ENABLE_SSL3, PR_TRUE)) ||
+ (rc = ldapssl_set_option(myld, SSL_ENABLE_TLS, PR_TRUE))) {
+ int prerr = PR_GetError();
+
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
+ "failed: unable to set SSL options ("
+ SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ prerr, slapd_pr_strerror(prerr));
+
+ }
+ if (secure == 1) {
+ /* tell bind code we are using SSL */
+ ldap_set_option(ld, LDAP_OPT_SSL, LDAP_OPT_ON);
+ }
+#endif /* !USE_OPENLDAP */
+ }
+ }
+
+ if (ld && (secure == 2)) {
+ /* We don't have a way to stash context data with the LDAP*, so we
+ stash the information in the client controls (currently unused).
+ We don't want to open the connection in ldap_init, since that's
+ not the semantic - the connection is not usually opened until
+ the first operation is sent, which is usually the bind - or
+ in this case, the start_tls - so we stash the start_tls so
+ we can do it in slapi_ldap_bind - note that this will get
+ cleaned up when the LDAP* is disposed of
+ */
+ LDAPControl start_tls_dummy_ctrl;
+ LDAPControl **clientctrls = NULL;
+
+ /* returns copy of controls */
+ ldap_get_option(ld, LDAP_OPT_CLIENT_CONTROLS, &clientctrls);
+
+ start_tls_dummy_ctrl.ldctl_oid = START_TLS_OID;
+ start_tls_dummy_ctrl.ldctl_value.bv_val = NULL;
+ start_tls_dummy_ctrl.ldctl_value.bv_len = 0;
+ start_tls_dummy_ctrl.ldctl_iscritical = 0;
+ slapi_add_control_ext(&clientctrls, &start_tls_dummy_ctrl, 1);
+ /* set option frees old list and copies the new list */
+ ldap_set_option(ld, LDAP_OPT_CLIENT_CONTROLS, clientctrls);
+ ldap_controls_free(clientctrls); /* free the copy */
+ }
+
+ slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_init_ext",
+ "Success: set up conn to [%s:%d]%s\n",
+ hostname, port,
+ (secure == 2) ? " using startTLS" :
+ ((secure == 1) ? " using SSL" : ""));
+done:
+ ldap_free_urldesc(ludp);
+
+ return( ld );
+}
+
+/*
+ * Function: slapi_ldap_init()
+ * Description: just like ldap_ssl_init() but also arranges for the LDAP
+ * session handle returned to be safely shareable by multiple threads
+ * if "shared" is non-zero.
+ * Returns:
+ * an LDAP session handle (NULL if some local error occurs).
+ */
+LDAP *
+slapi_ldap_init( char *ldaphost, int ldapport, int secure, int shared )
+{
+ return slapi_ldap_init_ext(NULL, ldaphost, ldapport, secure, shared, NULL);
+}
+
+/*
+ * Does the correct bind operation simple/sasl/cert depending
+ * on the arguments passed in. If the user specified to use
+ * starttls in init, this will do the starttls first. If using
+ * ssl or client cert auth, this will initialize the client side
+ * of that.
+ */
+int
+slapi_ldap_bind(
+ LDAP *ld, /* ldap connection */
+ const char *bindid, /* usually a bind DN for simple bind */
+ const char *creds, /* usually a password for simple bind */
+ const char *mech, /* name of mechanism */
+ LDAPControl **serverctrls, /* additional controls to send */
+ LDAPControl ***returnedctrls, /* returned controls */
+ struct timeval *timeout, /* timeout */
+ int *msgidp /* pass in non-NULL for async handling */
+)
+{
+ int rc = LDAP_SUCCESS;
+ LDAPControl **clientctrls = NULL;
+ int secure = 0;
+ struct berval bvcreds = {0, NULL};
+ LDAPMessage *result = NULL;
+ struct berval *servercredp = NULL;
+
+ /* do starttls if requested
+ NOTE - starttls is an extop, not a control, but we don't have
+ a place we can stash this information in the LDAP*, other
+ than the currently unused clientctrls */
+ ldap_get_option(ld, LDAP_OPT_CLIENT_CONTROLS, &clientctrls);
+ if (clientctrls && clientctrls[0] &&
+ slapi_control_present(clientctrls, START_TLS_OID, NULL, NULL)) {
+ secure = 2;
+ } else {
+#if defined(USE_OPENLDAP)
+ /* openldap doesn't have a SSL/TLS yes/no flag - so grab the
+ ldapurl, parse it, and see if it is a secure one */
+ char *ldapurl = NULL;
+ LDAPURLDesc *ludp = NULL;
+
+ ldap_get_option(ld, LDAP_OPT_URI, &ldapurl);
+ slapi_ldap_url_parse(ldapurl, &ludp, 0, &secure);
+ ldap_free_urldesc(ludp);
+ slapi_ch_free_string(&ldapurl);
+#else /* !USE_OPENLDAP */
+ ldap_get_option(ld, LDAP_OPT_SSL, &secure);
+#endif
+ }
+ ldap_controls_free(clientctrls);
+ ldap_set_option(ld, LDAP_OPT_CLIENT_CONTROLS, NULL);
+
+ if ((secure > 0) && mech && !strcmp(mech, LDAP_SASL_EXTERNAL)) {
+ /* SSL connections will use the server's security context
+ and cert for client auth */
+ rc = slapd_SSL_client_auth(ld);
+
+ if (rc != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: could not configure the server for cert "
+ "auth - error %d - make sure the server is "
+ "correctly configured for SSL/TLS\n", rc);
+ goto done;
+ } else {
+ slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
+ "Set up conn to use client auth\n");
+ }
+ bvcreds.bv_val = NULL; /* ignore username and passed in creds */
+ bvcreds.bv_len = 0; /* for external auth */
+ bindid = NULL;
+ } else { /* other type of auth */
+ bvcreds.bv_val = (char *)creds;
+ bvcreds.bv_len = creds ? strlen(creds) : 0;
+ }
+
+ if (secure == 2) { /* send start tls */
+ rc = ldap_start_tls_s(ld, NULL /* serverctrls?? */, NULL);
+ if (LDAP_SUCCESS != rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: could not send startTLS request: "
+ "error %d (%s)\n",
+ rc, ldap_err2string(rc));
+ goto done;
+ }
+ slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
+ "startTLS started on connection\n");
+ }
+
+ /* The connection has been set up - now do the actual bind, depending on
+ the mechanism and arguments */
+ if (!mech || (mech == LDAP_SASL_SIMPLE) ||
+ !strcmp(mech, LDAP_SASL_EXTERNAL)) {
+ int mymsgid = 0;
+
+ slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
+ "attempting %s bind with id [%s] creds [%s]\n",
+ mech ? mech : "SIMPLE",
+ bindid, creds);
+ if ((rc = ldap_sasl_bind(ld, bindid, mech, &bvcreds, serverctrls,
+ NULL /* clientctrls */, &mymsgid))) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: could not send bind request for id "
+ "[%s] mech [%s]: error %d (%s) %d (%s) %d (%s)\n",
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE",
+ rc, ldap_err2string(rc),
+ PR_GetError(), slapd_pr_strerror(PR_GetError()),
+ errno, slapd_system_strerror(errno));
+ goto done;
+ }
+
+ if (msgidp) { /* let caller process result */
+ *msgidp = mymsgid;
+ } else { /* process results */
+ rc = ldap_result(ld, mymsgid, LDAP_MSG_ALL, timeout, &result);
+ if (-1 == rc) { /* error */
+ rc = slapi_ldap_get_lderrno(ld, NULL, NULL);
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error reading bind response for id "
+ "[%s] mech [%s]: error %d (%s)\n",
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE",
+ rc, ldap_err2string(rc));
+ goto done;
+ } else if (rc == 0) { /* timeout */
+ rc = LDAP_TIMEOUT;
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: timeout after [%ld.%ld] seconds reading "
+ "bind response for [%s] mech [%s]\n",
+ timeout ? timeout->tv_sec : 0,
+ timeout ? timeout->tv_usec : 0,
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE");
+ goto done;
+ }
+ /* if we got here, we were able to read success result */
+ /* Get the controls sent by the server if requested */
+ if (returnedctrls) {
+ if ((rc = ldap_parse_result(ld, result, &rc, NULL, NULL,
+ NULL, returnedctrls,
+ 0)) != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: could not bind id "
+ "[%s] mech [%s]: error %d (%s)\n",
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE",
+ rc, ldap_err2string(rc));
+ goto done;
+ }
+ }
+
+ /* parse the bind result and get the ldap error code */
+ if ((rc = ldap_parse_sasl_bind_result(ld, result, &servercredp,
+ 0))) {
+ rc = slapi_ldap_get_lderrno(ld, NULL, NULL);
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: could not read bind results for id "
+ "[%s] mech [%s]: error %d (%s)\n",
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE",
+ rc, ldap_err2string(rc));
+ goto done;
+ }
+ }
+ } else {
+ /* a SASL mech - set the sasl ssf to 0 if using TLS/SSL */
+ /* openldap supports tls + sasl security */
+#if !defined(USE_OPENLDAP)
+ if (secure) {
+ sasl_ssf_t max_ssf = 0;
+ ldap_set_option(ld, LDAP_OPT_X_SASL_SSF_MAX, &max_ssf);
+ }
+#endif
+ rc = slapd_ldap_sasl_interactive_bind(ld, bindid, creds, mech,
+ serverctrls, returnedctrls,
+ msgidp);
+ if (LDAP_SUCCESS != rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
+ "Error: could not perform interactive bind for id "
+ "[%s] mech [%s]: error %d (%s)\n",
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE",
+ rc, ldap_err2string(rc));
+ }
+ }
+
+done:
+ slapi_ch_bvfree(&servercredp);
+ ldap_msgfree(result);
+
+ return rc;
+}
+
+/* the following implements the client side of sasl bind, for LDAP server
+ -> LDAP server SASL */
+
+typedef struct {
+ char *mech;
+ char *authid;
+ char *username;
+ char *passwd;
+ char *realm;
+} ldapSaslInteractVals;
+
+#ifdef HAVE_KRB5
+static void set_krb5_creds(
+ const char *authid,
+ const char *username,
+ const char *passwd,
+ const char *realm,
+ ldapSaslInteractVals *vals
+);
+#endif
+
+static void *
+ldap_sasl_set_interact_vals(LDAP *ld, const char *mech, const char *authid,
+ const char *username, const char *passwd,
+ const char *realm)
+{
+ ldapSaslInteractVals *vals = NULL;
+ char *idprefix = "";
+
+ vals = (ldapSaslInteractVals *)
+ slapi_ch_calloc(1, sizeof(ldapSaslInteractVals));
+
+ if (!vals) {
+ return NULL;
+ }
+
+ if (mech) {
+ vals->mech = slapi_ch_strdup(mech);
+ } else {
+ ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &vals->mech);
+ }
+
+ if (vals->mech && !strcasecmp(vals->mech, "DIGEST-MD5")) {
+ idprefix = "dn:"; /* prefix name and id with this string */
+ }
+
+ if (authid) { /* use explicit passed in value */
+ vals->authid = slapi_ch_smprintf("%s%s", idprefix, authid);
+ } else { /* use option value if any */
+ ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &vals->authid);
+ if (!vals->authid) {
+/* get server user id? */
+ vals->authid = slapi_ch_strdup("");
+ }
+ }
+
+ if (username) { /* use explicit passed in value */
+ vals->username = slapi_ch_smprintf("%s%s", idprefix, username);
+ } else { /* use option value if any */
+ ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &vals->username);
+ if (!vals->username) { /* use default sasl value */
+ vals->username = slapi_ch_strdup("");
+ }
+ }
+
+ if (passwd) {
+ vals->passwd = slapi_ch_strdup(passwd);
+ } else {
+ vals->passwd = slapi_ch_strdup("");
+ }
+
+ if (realm) {
+ vals->realm = slapi_ch_strdup(realm);
+ } else {
+ ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &vals->realm);
+ if (!vals->realm) { /* use default sasl value */
+ vals->realm = slapi_ch_strdup("");
+ }
+ }
+
+#ifdef HAVE_KRB5
+ if (mech && !strcmp(mech, "GSSAPI")) {
+ set_krb5_creds(authid, username, passwd, realm, vals);
+ }
+#endif /* HAVE_KRB5 */
+
+ return vals;
+}
+
+static void
+ldap_sasl_free_interact_vals(void *defaults)
+{
+ ldapSaslInteractVals *vals = defaults;
+
+ if (vals) {
+ slapi_ch_free_string(&vals->mech);
+ slapi_ch_free_string(&vals->authid);
+ slapi_ch_free_string(&vals->username);
+ slapi_ch_free_string(&vals->passwd);
+ slapi_ch_free_string(&vals->realm);
+ slapi_ch_free(&defaults);
+ }
+}
+
+static int
+ldap_sasl_get_val(ldapSaslInteractVals *vals, sasl_interact_t *interact, unsigned flags)
+{
+ const char *defvalue = interact->defresult;
+ int authtracelevel = SLAPI_LOG_SHELL; /* special auth tracing */
+
+ if (vals != NULL) {
+ switch(interact->id) {
+ case SASL_CB_AUTHNAME:
+ defvalue = vals->authid;
+ slapi_log_error(authtracelevel, "ldap_sasl_get_val",
+ "Using value [%s] for SASL_CB_AUTHNAME\n",
+ defvalue ? defvalue : "(null)");
+ break;
+ case SASL_CB_USER:
+ defvalue = vals->username;
+ slapi_log_error(authtracelevel, "ldap_sasl_get_val",
+ "Using value [%s] for SASL_CB_USER\n",
+ defvalue ? defvalue : "(null)");
+ break;
+ case SASL_CB_PASS:
+ defvalue = vals->passwd;
+ slapi_log_error(authtracelevel, "ldap_sasl_get_val",
+ "Using value [%s] for SASL_CB_PASS\n",
+ defvalue ? defvalue : "(null)");
+ break;
+ case SASL_CB_GETREALM:
+ defvalue = vals->realm;
+ slapi_log_error(authtracelevel, "ldap_sasl_get_val",
+ "Using value [%s] for SASL_CB_GETREALM\n",
+ defvalue ? defvalue : "(null)");
+ break;
+ }
+ }
+
+ if (defvalue != NULL) {
+ interact->result = defvalue;
+ if ((char *)interact->result == NULL)
+ return (LDAP_NO_MEMORY);
+ interact->len = strlen((char *)(interact->result));
+ }
+ return (LDAP_SUCCESS);
+}
+
+static int
+ldap_sasl_interact_cb(LDAP *ld, unsigned flags, void *defaults, void *prompts)
+{
+ sasl_interact_t *interact = NULL;
+ ldapSaslInteractVals *sasldefaults = defaults;
+ int rc;
+
+ if (prompts == NULL) {
+ return (LDAP_PARAM_ERROR);
+ }
+
+ for (interact = prompts; interact->id != SASL_CB_LIST_END; interact++) {
+ /* Obtain the default value */
+ if ((rc = ldap_sasl_get_val(sasldefaults, interact, flags)) != LDAP_SUCCESS) {
+ return (rc);
+ }
+ }
+
+ return (LDAP_SUCCESS);
+}
+
+/* figure out from the context and this error if we should
+ attempt to retry the bind */
+static int
+can_retry_bind(LDAP *ld, const char *mech, const char *bindid,
+ const char *creds, int rc, const char *errmsg)
+{
+ int localrc = 0;
+ if (errmsg && strstr(errmsg, "Ticket expired")) {
+ localrc = 1;
+ }
+
+ return localrc;
+}
+
+int
+slapd_ldap_sasl_interactive_bind(
+ LDAP *ld, /* ldap connection */
+ const char *bindid, /* usually a bind DN for simple bind */
+ const char *creds, /* usually a password for simple bind */
+ const char *mech, /* name of mechanism */
+ LDAPControl **serverctrls, /* additional controls to send */
+ LDAPControl ***returnedctrls, /* returned controls */
+ int *msgidp /* pass in non-NULL for async handling */
+)
+{
+ int rc = LDAP_SUCCESS;
+ int tries = 0;
+
+ while (tries < 2) {
+ void *defaults = ldap_sasl_set_interact_vals(ld, mech, bindid, bindid,
+ creds, NULL);
+ /* have to first set the defaults used by the callback function */
+ /* call the bind function */
+ /* openldap does not have the ext version - not sure how to get the
+ returned controls */
+#if defined(USE_OPENLDAP)
+ rc = ldap_sasl_interactive_bind_s(ld, bindid, mech, serverctrls,
+ NULL, LDAP_SASL_QUIET,
+ ldap_sasl_interact_cb, defaults);
+#else
+ rc = ldap_sasl_interactive_bind_ext_s(ld, bindid, mech, serverctrls,
+ NULL, LDAP_SASL_QUIET,
+ ldap_sasl_interact_cb, defaults,
+ returnedctrls);
+#endif
+ ldap_sasl_free_interact_vals(defaults);
+ if (LDAP_SUCCESS != rc) {
+ char *errmsg = NULL;
+ rc = slapi_ldap_get_lderrno(ld, NULL, &errmsg);
+ slapi_log_error(SLAPI_LOG_FATAL, "slapd_ldap_sasl_interactive_bind",
+ "Error: could not perform interactive bind for id "
+ "[%s] mech [%s]: error %d (%s) (%s)\n",
+ bindid ? bindid : "(anon)",
+ mech ? mech : "SIMPLE",
+ rc, ldap_err2string(rc), errmsg);
+ if (can_retry_bind(ld, mech, bindid, creds, rc, errmsg)) {
+ ; /* pass through to retry one time */
+ } else {
+ break; /* done - fail - cannot retry */
+ }
+ } else {
+ break; /* done - success */
+ }
+ tries++;
+ }
+
+ return rc;
+}
+
+#ifdef HAVE_KRB5
+#include <krb5.h>
+
+/* for some reason this is not in the public API?
+ but it is documented e.g. man kinit */
+#ifndef KRB5_ENV_CCNAME
+#define KRB5_ENV_CCNAME "KRB5CCNAME"
+#endif
+
+static void
+show_one_credential(int authtracelevel,
+ krb5_context ctx, krb5_creds *cred)
+{
+ char *logname = "show_one_credential";
+ krb5_error_code rc;
+ char *name = NULL, *sname = NULL;
+ char startts[BUFSIZ], endts[BUFSIZ], renewts[BUFSIZ];
+
+ if ((rc = krb5_unparse_name(ctx, cred->client, &name))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get client name from credential: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+ if ((rc = krb5_unparse_name(ctx, cred->server, &sname))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get server name from credential: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+ if (!cred->times.starttime) {
+ cred->times.starttime = cred->times.authtime;
+ }
+ krb5_timestamp_to_sfstring((krb5_timestamp)cred->times.starttime,
+ startts, sizeof(startts), NULL);
+ krb5_timestamp_to_sfstring((krb5_timestamp)cred->times.endtime,
+ endts, sizeof(endts), NULL);
+ krb5_timestamp_to_sfstring((krb5_timestamp)cred->times.renew_till,
+ renewts, sizeof(renewts), NULL);
+
+ slapi_log_error(authtracelevel, logname,
+ "\tKerberos credential: client [%s] server [%s] "
+ "start time [%s] end time [%s] renew time [%s] "
+ "flags [0x%x]\n", name, sname, startts, endts,
+ renewts, (uint32_t)cred->ticket_flags);
+
+cleanup:
+ krb5_free_unparsed_name(ctx, name);
+ krb5_free_unparsed_name(ctx, sname);
+
+ return;
+}
+
+/*
+ * Call this after storing the credentials in the cache
+ */
+static void
+show_cached_credentials(int authtracelevel,
+ krb5_context ctx, krb5_ccache cc,
+ krb5_principal princ)
+{
+ char *logname = "show_cached_credentials";
+ krb5_error_code rc = 0;
+ krb5_creds creds;
+ krb5_cc_cursor cur;
+ char *princ_name = NULL;
+
+ if ((rc = krb5_unparse_name(ctx, princ, &princ_name))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get principal name from principal: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ slapi_log_error(authtracelevel, logname,
+ "Ticket cache: %s:%s\nDefault principal: %s\n\n",
+ krb5_cc_get_type(ctx, cc),
+ krb5_cc_get_name(ctx, cc), princ_name);
+
+ if ((rc = krb5_cc_start_seq_get(ctx, cc, &cur))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get cursor to iterate cached credentials: "
+ "%d (%s)\n", rc, error_message(rc));
+ goto cleanup;
+ }
+
+ while (!(rc = krb5_cc_next_cred(ctx, cc, &cur, &creds))) {
+ show_one_credential(authtracelevel, ctx, &creds);
+ krb5_free_cred_contents(ctx, &creds);
+ }
+ if (rc == KRB5_CC_END) {
+ if ((rc = krb5_cc_end_seq_get(ctx, cc, &cur))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not close cached credentials cursor: "
+ "%d (%s)\n", rc, error_message(rc));
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ krb5_free_unparsed_name(ctx, princ_name);
+
+ return;
+}
+
+static int
+looks_like_a_dn(const char *username)
+{
+ return (username && strchr(username, '='));
+}
+
+static int
+credentials_are_valid(
+ krb5_context ctx,
+ krb5_ccache cc,
+ krb5_principal princ,
+ const char *princ_name,
+ int *rc
+)
+{
+ char *logname = "credentials_are_valid";
+ int myrc = 0;
+ krb5_creds mcreds; /* match these values */
+ krb5_creds creds; /* returned creds */
+ char *tgs_princ_name = NULL;
+ krb5_timestamp currenttime;
+ int authtracelevel = SLAPI_LOG_SHELL; /* special auth tracing */
+ int realm_len;
+ char *realm_str;
+ int time_buffer = 30; /* seconds - go ahead and renew if creds are
+ about to expire */
+
+ memset(&mcreds, 0, sizeof(mcreds));
+ memset(&creds, 0, sizeof(creds));
+ *rc = 0;
+ if (!cc) {
+ /* ok - no error */
+ goto cleanup;
+ }
+
+ /* have to construct the tgs server principal in
+ order to set mcreds.server required in order
+ to use krb5_cc_retrieve_creds() */
+ /* get default realm first */
+ realm_len = krb5_princ_realm(ctx, princ)->length;
+ realm_str = krb5_princ_realm(ctx, princ)->data;
+ tgs_princ_name = slapi_ch_smprintf("%s/%*s@%*s", KRB5_TGS_NAME,
+ realm_len, realm_str,
+ realm_len, realm_str);
+
+ if ((*rc = krb5_parse_name(ctx, tgs_princ_name, &mcreds.server))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could parse principal [%s]: %d (%s)\n",
+ tgs_princ_name, *rc, error_message(*rc));
+ goto cleanup;
+ }
+
+ mcreds.client = princ;
+ if ((*rc = krb5_cc_retrieve_cred(ctx, cc, 0, &mcreds, &creds))) {
+ if (*rc == KRB5_CC_NOTFOUND) {
+ /* ok - no creds for this princ in the cache */
+ *rc = 0;
+ }
+ goto cleanup;
+ }
+
+ /* have the creds - now look at the timestamp */
+ if ((*rc = krb5_timeofday(ctx, &currenttime))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get current time: %d (%s)\n",
+ *rc, error_message(*rc));
+ goto cleanup;
+ }
+
+ if (currenttime > (creds.times.endtime + time_buffer)) {
+ slapi_log_error(authtracelevel, logname,
+ "Credentials for [%s] have expired or will soon "
+ "expire - now [%d] endtime [%d]\n", princ_name,
+ currenttime, creds.times.endtime);
+ goto cleanup;
+ }
+
+ myrc = 1; /* credentials are valid */
+cleanup:
+ krb5_free_cred_contents(ctx, &creds);
+ slapi_ch_free_string(&tgs_princ_name);
+ if (mcreds.server) {
+ krb5_free_principal(ctx, mcreds.server);
+ }
+
+ return myrc;
+}
+
+/*
+ * This implementation assumes that we want to use the
+ * keytab from the default keytab env. var KRB5_KTNAME
+ * as. This code is very similar to kinit -k -t. We
+ * get a krb context, get the default keytab, get
+ * the credentials from the keytab, authenticate with
+ * those credentials, create a ccache, store the
+ * credentials in the ccache, and set the ccache
+ * env var to point to those credentials.
+ */
+static void
+set_krb5_creds(
+ const char *authid,
+ const char *username,
+ const char *passwd,
+ const char *realm,
+ ldapSaslInteractVals *vals
+)
+{
+ char *logname = "set_krb5_creds";
+ const char *cc_type = "MEMORY"; /* keep cred cache in memory */
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal princ = NULL;
+ char *princ_name = NULL;
+ krb5_error_code rc = 0;
+ krb5_creds creds;
+ krb5_keytab kt = NULL;
+ char *cc_name = NULL;
+ char ktname[MAX_KEYTAB_NAME_LEN];
+ static char cc_env_name[1024+32]; /* size from ccdefname.c */
+ int new_ccache = 0;
+ int authtracelevel = SLAPI_LOG_SHELL; /* special auth tracing
+ not sure what shell was
+ used for, does not
+ appear to be used
+ currently */
+
+ /* probably have to put a mutex around this whole thing, to avoid
+ problems with reentrancy, since we are setting a "global"
+ variable via an environment variable */
+
+ /* wipe this out so we can safely free it later if we
+ short circuit */
+ memset(&creds, 0, sizeof(creds));
+
+ /* initialize the kerberos context */
+ if ((rc = krb5_init_context(&ctx))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not init Kerberos context: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* see if there is already a ccache, and see if there are
+ creds in the ccache */
+ /* grab the default ccache - note: this does not open the cache */
+ if ((rc = krb5_cc_default(ctx, &cc))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get default Kerberos ccache: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* use this cache - construct the full cache name */
+ cc_name = slapi_ch_smprintf("%s:%s", krb5_cc_get_type(ctx, cc),
+ krb5_cc_get_name(ctx, cc));
+
+ /* grab the principal from the ccache - will fail if there
+ is no ccache */
+ if ((rc = krb5_cc_get_principal(ctx, cc, &princ))) {
+ if (KRB5_FCC_NOFILE == rc) { /* no cache - ok */
+ slapi_log_error(authtracelevel, logname,
+ "The default credentials cache [%s] not found: "
+ "will create a new one.\n", cc_name);
+ /* close the cache - we will create a new one below */
+ krb5_cc_close(ctx, cc);
+ cc = NULL;
+ slapi_ch_free_string(&cc_name);
+ /* fall through to the keytab auth code below */
+ } else { /* fatal */
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not open default Kerberos ccache [%s]: "
+ "%d (%s)\n", cc_name, rc, error_message(rc));
+ goto cleanup;
+ }
+ } else { /* have a valid ccache && found principal */
+ if ((rc = krb5_unparse_name(ctx, princ, &princ_name))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Unable to get name of principal from ccache [%s]: "
+ "%d (%s)\n", cc_name, rc, error_message(rc));
+ goto cleanup;
+ }
+ slapi_log_error(authtracelevel, logname,
+ "Using principal [%s] from ccache [%s]\n",
+ princ_name, cc_name);
+ }
+
+ /* if this is not our type of ccache, there is nothing more we can
+ do - just punt and let sasl/gssapi take it's course - this
+ usually means there has been an external kinit e.g. in the
+ start up script, and it is the responsibility of the script to
+ renew those credentials or face lots of sasl/gssapi failures
+ This means, however, that the caller MUST MAKE SURE THERE IS NO
+ DEFAULT CCACHE FILE or the server will attempt to use it (and
+ likely fail) - THERE MUST BE NO DEFAULT CCACHE FILE IF YOU WANT
+ THE SERVER TO AUTHENTICATE WITH THE KEYTAB
+ NOTE: cc types are case sensitive and always upper case */
+ if (cc && strcmp(cc_type, krb5_cc_get_type(ctx, cc))) {
+ static int errmsgcounter = 0;
+ int loglevel = SLAPI_LOG_FATAL;
+ if (errmsgcounter) {
+ loglevel = authtracelevel;
+ }
+ /* make sure we log this message once, in case the user has
+ done something unintended, we want to make sure they know
+ about it. However, if the user knows what he/she is doing,
+ by using an external ccache file, they probably don't want
+ to be notified with an error every time. */
+ slapi_log_error(loglevel, logname,
+ "The server will use the external SASL/GSSAPI "
+ "credentials cache [%s:%s]. If you want the "
+ "server to automatically authenticate with its "
+ "keytab, you must remove this cache. If you "
+ "did not intend to use this cache, you will likely "
+ "see many SASL/GSSAPI authentication failures.\n",
+ krb5_cc_get_type(ctx, cc), krb5_cc_get_name(ctx, cc));
+ errmsgcounter++;
+ goto cleanup;
+ }
+
+ /* need to figure out which principal to use
+ 1) use the one from the ccache
+ 2) use username
+ 3) construct one in the form ldap/fqdn@REALM
+ */
+ if (!princ && username && !looks_like_a_dn(username) &&
+ (rc = krb5_parse_name(ctx, username, &princ))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Error: could not convert [%s] into a kerberos "
+ "principal: %d (%s)\n", username,
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* if still no principal, construct one */
+ if (!princ &&
+ (rc = krb5_sname_to_principal(ctx, NULL, "ldap",
+ KRB5_NT_SRV_HST, &princ))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Error: could not construct ldap service "
+ "principal: %d (%s)\n", rc, error_message(rc));
+ goto cleanup;
+ }
+
+ if ((rc = krb5_unparse_name(ctx, princ, &princ_name))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Unable to get name of principal: "
+ "%d (%s)\n", rc, error_message(rc));
+ goto cleanup;
+ }
+
+ slapi_log_error(authtracelevel, logname,
+ "Using principal named [%s]\n", princ_name);
+
+ /* grab the credentials from the ccache, if any -
+ if the credentials are still valid, we do not have
+ to authenticate again */
+ if (credentials_are_valid(ctx, cc, princ, princ_name, &rc)) {
+ slapi_log_error(authtracelevel, logname,
+ "Credentials for principal [%s] are still "
+ "valid - no auth is necessary.\n",
+ princ_name);
+ goto cleanup;
+ } else if (rc) { /* some error other than "there are no credentials" */
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Unable to verify cached credentials for "
+ "principal [%s]: %d (%s)\n", princ_name,
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* find our default keytab */
+ if ((rc = krb5_kt_default(ctx, &kt))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Unable to get default keytab: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* get name of keytab for debugging purposes */
+ if ((rc = krb5_kt_get_name(ctx, kt, ktname, sizeof(ktname)))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Unable to get name of default keytab: %d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+
+ slapi_log_error(authtracelevel, logname,
+ "Using keytab named [%s]\n", ktname);
+
+ /* now do the actual kerberos authentication using
+ the keytab, and get the creds */
+ rc = krb5_get_init_creds_keytab(ctx, &creds, princ, kt,
+ 0, NULL, NULL);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not get initial credentials for principal [%s] "
+ "in keytab [%s]: %d (%s)\n",
+ princ_name, ktname, rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* completely done with the keytab now, close it */
+ krb5_kt_close(ctx, kt);
+ kt = NULL; /* no double free */
+
+ /* we now have the creds and the principal to which the
+ creds belong - use or allocate a new memory based
+ cache to hold the creds */
+ if (!cc_name) {
+#if HAVE_KRB5_CC_NEW_UNIQUE
+ /* krb5_cc_new_unique is a new convenience function which
+ generates a new unique name and returns a memory
+ cache with that name */
+ if ((rc = krb5_cc_new_unique(ctx, cc_type, NULL, &cc))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not create new unique memory ccache: "
+ "%d (%s)\n",
+ rc, error_message(rc));
+ goto cleanup;
+ }
+ cc_name = slapi_ch_smprintf("%s:%s", cc_type,
+ krb5_cc_get_name(ctx, cc));
+#else
+ /* store the cache in memory - krb5_init_context uses malloc
+ to create the ctx, so the address should be unique enough
+ for our purposes */
+ if (!(cc_name = slapi_ch_smprintf("%s:%p", cc_type, ctx))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could create Kerberos memory ccache: "
+ "out of memory\n");
+ rc = 1;
+ goto cleanup;
+ }
+#endif
+ slapi_log_error(authtracelevel, logname,
+ "Generated new memory ccache [%s]\n", cc_name);
+ new_ccache = 1; /* need to set this in env. */
+ } else {
+ slapi_log_error(authtracelevel, logname,
+ "Using existing ccache [%s]\n", cc_name);
+ }
+
+ /* krb5_cc_resolve is basically like an init -
+ this creates the cache structure, and creates a slot
+ for the cache in the static linked list in memory, if
+ there is not already a slot -
+ see cc_memory.c for details
+ cc could already have been created by new_unique above
+ */
+ if (!cc && (rc = krb5_cc_resolve(ctx, cc_name, &cc))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not create ccache [%s]: %d (%s)\n",
+ cc_name, rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* wipe out previous contents of cache for this principal, if any */
+ if ((rc = krb5_cc_initialize(ctx, cc, princ))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not initialize ccache [%s] for the new "
+ "credentials for principal [%s]: %d (%s)\n",
+ cc_name, princ_name, rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* store the credentials in the cache */
+ if ((rc = krb5_cc_store_cred(ctx, cc, &creds))) {
+ slapi_log_error(SLAPI_LOG_FATAL, logname,
+ "Could not store the credentials in the "
+ "ccache [%s] for principal [%s]: %d (%s)\n",
+ cc_name, princ_name, rc, error_message(rc));
+ goto cleanup;
+ }
+
+ /* now, do a "klist" to show the credential information, and log it */
+ show_cached_credentials(authtracelevel, ctx, cc, princ);
+
+ /* set the CC env var to the value of the cc cache name */
+ /* since we can't pass krb5 context up and out of here
+ and down through the ldap sasl layer, we set this
+ env var so that calls to krb5_cc_default_name will
+ use this */
+ if (new_ccache) {
+ PR_snprintf(cc_env_name, sizeof(cc_env_name),
+ "%s=%s", KRB5_ENV_CCNAME, cc_name);
+ PR_SetEnv(cc_env_name);
+ slapi_log_error(authtracelevel, logname,
+ "Set new env for ccache: [%s]\n",
+ cc_env_name);
+ }
+
+cleanup:
+ /* use NULL as username and authid */
+ slapi_ch_free_string(&vals->username);
+ slapi_ch_free_string(&vals->authid);
+
+ krb5_free_unparsed_name(ctx, princ_name);
+ if (kt) { /* NULL not allowed */
+ krb5_kt_close(ctx, kt);
+ }
+ if (creds.client == princ) {
+ creds.client = NULL;
+ }
+ krb5_free_cred_contents(ctx, &creds);
+ slapi_ch_free_string(&cc_name);
+ krb5_free_principal(ctx, princ);
+ if (cc) {
+ krb5_cc_close(ctx, cc);
+ }
+ if (ctx) { /* cannot pass NULL to free context */
+ krb5_free_context(ctx);
+ }
+ return;
+}
+
+#endif /* HAVE_KRB5 */
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 358a745a..d806809e 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -52,7 +52,6 @@
#include "ldap.h"
#include <sslproto.h>
-#include <ldap_ssl.h>
#undef OFF
#undef LITTLE_ENDIAN
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index d90d2b49..1eac8489 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -179,6 +179,7 @@ do_modify( Slapi_PBlock *pb )
/* collect modifications & save for later */
slapi_mods_init(&smods, 0);
+ len = -1;
for ( tag = ber_first_element( ber, &len, &last );
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
tag = ber_next_element( ber, &len, last ) )
@@ -186,6 +187,7 @@ do_modify( Slapi_PBlock *pb )
ber_int_t mod_op;
mod = (LDAPMod *) slapi_ch_malloc( sizeof(LDAPMod) );
mod->mod_bvalues = NULL;
+ len = -1; /* reset - len is not used */
if ( ber_scanf( ber, "{i{a[V]}}", &mod_op, &type,
&mod->mod_bvalues ) == LBER_ERROR )
@@ -264,7 +266,7 @@ do_modify( Slapi_PBlock *pb )
}
/* check for decoding error */
- if ( tag == LBER_ERROR )
+ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) )
{
op_shared_log_error_access (pb, "MOD", dn, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL );
diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c
index b8ca7fe7..e27b96e9 100644
--- a/ldap/servers/slapd/modrdn.c
+++ b/ldap/servers/slapd/modrdn.c
@@ -385,7 +385,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args)
}
else
{
- ldap_value_free(rdns);
+ slapi_ldap_value_free(rdns);
}
/* check if created attributes are used in the new RDN */
@@ -409,7 +409,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args)
}
else
{
- ldap_value_free(rdns);
+ slapi_ldap_value_free(rdns);
}
if (newsuperior != NULL)
diff --git a/ldap/servers/slapd/modutil.c b/ldap/servers/slapd/modutil.c
index eec7b33b..deed1ccb 100644
--- a/ldap/servers/slapd/modutil.c
+++ b/ldap/servers/slapd/modutil.c
@@ -816,7 +816,7 @@ slapi_mod_dump(LDAPMod *mod, int n)
len = LDIF_SIZE_NEEDED( len, mod->mod_bvalues[i]->bv_len ) + 1;
buf = slapi_ch_malloc( len );
bufp = buf;
- ldif_put_type_and_value( &bufp, mod->mod_type, mod->mod_bvalues[i]->bv_val, mod->mod_bvalues[i]->bv_len );
+ slapi_ldif_put_type_and_value_with_options( &bufp, mod->mod_type, mod->mod_bvalues[i]->bv_val, mod->mod_bvalues[i]->bv_len, 0 );
*bufp = '\0';
LDAPDebug( LDAP_DEBUG_ANY, "smod %d - value: %s", n, buf, 0);
slapi_ch_free( (void**)&buf );
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index 85a19a45..510b257c 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -115,6 +115,43 @@ get_operation_object_type()
return operation_type;
}
+#if defined(USE_OPENLDAP)
+/* openldap doesn't have anything like this, nor does it have
+ a way to portably and without cheating discover the
+ sizeof BerElement - see lber_pvt.h for the trick used
+ for BerElementBuffer
+ so we just allocate everything separately
+ If we wanted to get fancy, we could use LBER_OPT_MEMORY_FNS
+ to override the ber malloc, realloc, etc. and use
+ LBER_OPT_BER_MEMCTX to provide callback data for use
+ with those functions
+*/
+static void*
+ber_special_alloc(size_t size, BerElement **ppBer)
+{
+ void *mem = NULL;
+
+ /* starts out with a null buffer - will grow as needed */
+ *ppBer = ber_alloc_t(0);
+
+ /* Make sure mem size requested is aligned */
+ if (0 != ( size & 0x03 )) {
+ size += (sizeof(ber_int_t) - (size & 0x03));
+ }
+
+ mem = slapi_ch_malloc(size);
+
+ return mem;
+}
+
+static void
+ber_special_free(void* buf, BerElement *ber)
+{
+ ber_free(ber, 1);
+ slapi_ch_free(&buf);
+}
+#endif
+
/*
* Allocate a new Slapi_Operation.
* The flag parameter indicates whether the the operation is
diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c
index 2953b1b8..5c87303a 100644
--- a/ldap/servers/slapd/passwd_extop.c
+++ b/ldap/servers/slapd/passwd_extop.c
@@ -57,6 +57,8 @@
#include <prio.h>
+#include <plbase64.h>
+
#include <ssl.h>
#include "slap.h"
#include "slapi-plugin.h"
@@ -233,7 +235,7 @@ static int passwd_modify_userpassword(Slapi_PBlock *pb_orig, Slapi_Entry *target
/* Generate a new, basic random password */
static int passwd_modify_generate_basic_passwd( int passlen, char **genpasswd )
{
- unsigned char *data = NULL;
+ char *data = NULL;
char *enc = NULL;
int datalen = LDAP_EXTOP_PASSMOD_RANDOM_BYTES;
int enclen = LDAP_EXTOP_PASSMOD_GEN_PASSWD_LEN + 1;
@@ -247,16 +249,14 @@ static int passwd_modify_generate_basic_passwd( int passlen, char **genpasswd )
enclen = datalen * 4; /* allocate the large enough space */
}
- data = (unsigned char *)slapi_ch_calloc( datalen, 1 );
- enc = (char *)slapi_ch_calloc( enclen, 1 );
+ data = slapi_ch_calloc( datalen, 1 );
/* get random bytes from NSS */
- PK11_GenerateRandom( data, datalen );
+ PK11_GenerateRandom( (unsigned char *)data, datalen );
/* b64 encode the random bytes to get a password made up
- * of printable characters. ldif_base64_encode() will
- * zero-terminate the string */
- (void)ldif_base64_encode( data, enc, passlen, -1 );
+ * of printable characters. */
+ enc = PL_Base64Encode( data, datalen, NULL );
/* This will get freed by the caller */
*genpasswd = slapi_ch_malloc( 1 + passlen );
@@ -264,7 +264,7 @@ static int passwd_modify_generate_basic_passwd( int passlen, char **genpasswd )
/* trim the password to the proper length */
PL_strncpyz( *genpasswd, enc, passlen + 1 );
- slapi_ch_free( (void **)&data );
+ slapi_ch_free_string( &data );
slapi_ch_free_string( &enc );
return LDAP_SUCCESS;
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 7955e86a..afcdb0b2 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -1280,6 +1280,9 @@ int connection_acquire_nolock (Connection *conn);
int connection_release_nolock (Connection *conn);
int connection_is_free (Connection *conn);
int connection_is_active_nolock (Connection *conn);
+#if defined(USE_OPENLDAP)
+ber_slen_t openldap_read_function(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len);
+#endif
/*
* saslbind.c
diff --git a/ldap/servers/slapd/rdn.c b/ldap/servers/slapd/rdn.c
index 026c80c7..97b0719f 100644
--- a/ldap/servers/slapd/rdn.c
+++ b/ldap/servers/slapd/rdn.c
@@ -96,7 +96,7 @@ slapi_rdn_init_dn(Slapi_RDN *rdn,const char *dn)
if(dns!=NULL)
{
rdn->rdn= slapi_ch_strdup(dns[0]);
- ldap_value_free(dns);
+ slapi_ldap_value_free(dns);
}
}
}
@@ -151,7 +151,7 @@ slapi_rdn_get_rdns(Slapi_RDN *rdn)
{
if(rdn->rdns!=NULL)
{
- ldap_value_free(rdn->rdns);
+ slapi_ldap_value_free(rdn->rdns);
rdn->rdns= NULL;
}
if(rdn->rdn!=NULL)
@@ -182,7 +182,7 @@ slapi_rdn_done(Slapi_RDN *rdn)
if(rdn!=NULL)
{
slapi_ch_free((void**)&(rdn->rdn));
- ldap_value_free(rdn->rdns);
+ slapi_ldap_value_free(rdn->rdns);
slapi_rdn_init(rdn);
}
}
diff --git a/ldap/servers/slapd/referral.c b/ldap/servers/slapd/referral.c
index 81adccd4..458da813 100644
--- a/ldap/servers/slapd/referral.c
+++ b/ldap/servers/slapd/referral.c
@@ -315,6 +315,7 @@ adjust_referral_basedn( char **urlp, const Slapi_DN *refsdn,
LDAPURLDesc *ludp = NULL;
char *p, *refdn_norm;
int rc = 0;
+ int secure = 0;
PR_ASSERT( urlp != NULL );
PR_ASSERT( *urlp != NULL );
@@ -326,22 +327,16 @@ adjust_referral_basedn( char **urlp, const Slapi_DN *refsdn,
return;
}
- rc = ldap_url_parse( *urlp, &ludp );
-
- if ((rc != 0) &&
- (rc != LDAP_URL_ERR_NODN))
- /*
- * rc != LDAP_URL_ERR_NODN is to circumvent a pb in the C-SDK
- * in ldap_url_parse. The function will return an error if the
- * URL contains no DN (though it is a valid URL according to
- * RFC 2255.
- */
+ rc = slapi_ldap_url_parse( *urlp, &ludp, 0, &secure );
+
+ if (rc != 0)
{
/* Nothing to do, just return */
+ /* log bogus url? */
return;
}
- if (ludp && (ludp->lud_dn != NULL)) {
+ if (ludp && (ludp->lud_dn != NULL) && (ludp->lud_dn[0])) {
refdn_norm = slapi_dn_normalize( slapi_ch_strdup( ludp->lud_dn ));
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index 3bee6f8c..ce08c5a6 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -682,7 +682,7 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
LDAPDebug(LDAP_DEBUG_TRACE, "sasl library mechs: %s\n", str, 0, 0);
/* merge into result set */
dupstr = slapi_ch_strdup(str);
- others = str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
+ others = slapi_str2charray_ext(dupstr, ",", 0 /* don't list duplicate mechanisms */);
charray_merge(&ret, others, 1);
charray_free(others);
slapi_ch_free((void**)&dupstr);
@@ -722,7 +722,7 @@ ids_sasl_mech_supported(Slapi_PBlock *pb, sasl_conn_t *sasl_conn, const char *me
}
dupstr = slapi_ch_strdup(str);
- mechs = str2charray(dupstr, ",");
+ mechs = slapi_str2charray(dupstr, ",");
for (i = 0; mechs[i] != NULL; i++) {
if (strcasecmp(mech, mechs[i]) == 0) {
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index c2600f41..3eb3ab82 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -1997,7 +1997,7 @@ static char **read_dollar_values ( char *vals) {
}
}
vals[k] = '\0';
- retVal = str2charray (vals, "$");
+ retVal = slapi_str2charray (vals, "$");
return retVal;
}
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index fd2c7d73..7fd67613 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -188,9 +188,6 @@ typedef struct symbol_t {
* XXXmcs: these are defined by ldap.h or ldap-extension.h,
* but only in a newer release than we use with DS today.
*/
-#ifndef LDAP_CONTROL_AUTH_REQUEST
-#define LDAP_CONTROL_AUTH_REQUEST "2.16.840.1.113730.3.4.16"
-#endif
#ifndef LDAP_CONTROL_AUTH_RESPONSE
#define LDAP_CONTROL_AUTH_RESPONSE "2.16.840.1.113730.3.4.15"
#endif
@@ -2047,8 +2044,12 @@ extern char *attr_dataversion;
#define SLAPD_SNMP_UPDATE_INTERVAL (10 * 1000) /* 10 seconds */
+#ifndef LDAP_AUTH_KRBV41
#define LDAP_AUTH_KRBV41 0x81L
+#endif
+#ifndef LDAP_AUTH_KRBV42
#define LDAP_AUTH_KRBV42 0x82L
+#endif
/* for timing certain operations */
#ifdef USE_TIMERS
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 135f49b7..e04fad9b 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -129,18 +129,143 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...)
/*
* filter types
+ * openldap defines these, but not mozldap
*/
+#ifndef LDAP_FILTER_AND
#define LDAP_FILTER_AND 0xa0L
+#endif
+#ifndef LDAP_FILTER_OR
#define LDAP_FILTER_OR 0xa1L
+#endif
+#ifndef LDAP_FILTER_NOT
#define LDAP_FILTER_NOT 0xa2L
+#endif
+#ifndef LDAP_FILTER_EQUALITY
#define LDAP_FILTER_EQUALITY 0xa3L
+#endif
+#ifndef LDAP_FILTER_SUBSTRINGS
#define LDAP_FILTER_SUBSTRINGS 0xa4L
+#endif
+#ifndef LDAP_FILTER_GE
#define LDAP_FILTER_GE 0xa5L
+#endif
+#ifndef LDAP_FILTER_LE
#define LDAP_FILTER_LE 0xa6L
+#endif
+#ifndef LDAP_FILTER_PRESENT
#define LDAP_FILTER_PRESENT 0x87L
+#endif
+#ifndef LDAP_FILTER_APPROX
#define LDAP_FILTER_APPROX 0xa8L
-#define LDAP_FILTER_EXTENDED 0xa9L
+#endif
+
+#ifndef LDAP_FILTER_EXTENDED
+#ifdef LDAP_FILTER_EXT
+#define LDAP_FILTER_EXTENDED LDAP_FILTER_EXT
+#else
+#define LDAP_FILTER_EXTENDED 0xa9L
+#endif
+#endif
+
+#ifndef LBER_END_OF_SEQORSET
+#define LBER_END_OF_SEQORSET ((ber_tag_t) -2) /* 0xfffffffeU */
+#endif
+
+#ifndef LDAP_CHANGETYPE_ADD
+#ifdef LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD
+#define LDAP_CHANGETYPE_ADD LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_ADD
+#else
+#define LDAP_CHANGETYPE_ADD 1
+#endif
+#endif
+#ifndef LDAP_CHANGETYPE_DELETE
+#ifdef LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE
+#define LDAP_CHANGETYPE_DELETE LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_DELETE
+#else
+#define LDAP_CHANGETYPE_DELETE 2
+#endif
+#endif
+#ifndef LDAP_CHANGETYPE_MODIFY
+#ifdef LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY
+#define LDAP_CHANGETYPE_MODIFY LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_MODIFY
+#else
+#define LDAP_CHANGETYPE_MODIFY 4
+#endif
+#endif
+#ifndef LDAP_CHANGETYPE_MODDN
+#ifdef LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME
+#define LDAP_CHANGETYPE_MODDN LDAP_CONTROL_PERSSIT_ENTRY_CHANGE_RENAME
+#else
+#define LDAP_CHANGETYPE_MODDN 8
+#endif
+#endif
+#ifndef LDAP_CHANGETYPE_ANY
+#define LDAP_CHANGETYPE_ANY (1|2|4|8)
+#endif
+
+#ifndef LDAP_CONTROL_PERSISTENTSEARCH
+#ifdef LDAP_CONTROL_PERSIST_REQUEST
+#define LDAP_CONTROL_PERSISTENTSEARCH LDAP_CONTROL_PERSIST_REQUEST
+#else
+#define LDAP_CONTROL_PERSISTENTSEARCH "2.16.840.1.113730.3.4.3"
+#endif
+#endif
+#ifndef LDAP_CONTROL_ENTRYCHANGE
+#ifdef LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE
+#define LDAP_CONTROL_ENTRYCHANGE LDAP_CONTROL_PERSIST_ENTRY_CHANGE_NOTICE
+#else
+#define LDAP_CONTROL_ENTRYCHANGE "2.16.840.1.113730.3.4.7"
+#endif
+#endif
+
+#ifndef LDAP_CONTROL_PWEXPIRED
+#define LDAP_CONTROL_PWEXPIRED "2.16.840.1.113730.3.4.4"
+#endif
+#ifndef LDAP_CONTROL_PWEXPIRING
+#define LDAP_CONTROL_PWEXPIRING "2.16.840.1.113730.3.4.5"
+#endif
+#ifndef LDAP_X_CONTROL_PWPOLICY_REQUEST
+#ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
+#define LDAP_X_CONTROL_PWPOLICY_REQUEST LDAP_CONTROL_PASSWORDPOLICYREQUEST
+#else
+#define LDAP_X_CONTROL_PWPOLICY_REQUEST "1.3.6.1.4.1.42.2.27.8.5.1"
+#endif
+#endif
+#ifndef LDAP_X_CONTROL_PWPOLICY_RESPONSE
+#ifdef LDAP_CONTROL_PASSWORDPOLICYRESPONSE
+#define LDAP_X_CONTROL_PWPOLICY_RESPONSE LDAP_CONTROL_PASSWORDPOLICYRESPONSE
+#else
+#define LDAP_X_CONTROL_PWPOLICY_RESPONSE "1.3.6.1.4.1.42.2.27.8.5.1"
+#endif
+#endif
+
+#ifndef LDAP_CONTROL_PROXYAUTH
+#define LDAP_CONTROL_PROXYAUTH "2.16.840.1.113730.3.4.12" /* version 1 */
+#endif
+#ifndef LDAP_CONTROL_PROXIEDAUTH
+#ifdef LDAP_CONTROL_PROXY_AUTHZ
+#define LDAP_CONTROL_PROXIEDAUTH LDAP_CONTROL_PROXY_AUTHZ
+#else
+#define LDAP_CONTROL_PROXIEDAUTH "2.16.840.1.113730.3.4.18" /* version 2 */
+#endif
+#endif
+
+#ifndef LDAP_CONTROL_AUTH_REQUEST
+#define LDAP_CONTROL_AUTH_REQUEST "2.16.840.1.113730.3.4.16"
+#endif
+
+#ifndef LDAP_SORT_CONTROL_MISSING
+#define LDAP_SORT_CONTROL_MISSING 0x3C /* 60 (server side sort extn) */
+#endif
+#ifndef LDAP_INDEX_RANGE_ERROR
+#define LDAP_INDEX_RANGE_ERROR 0x3D /* 61 (VLV extn) */
+#endif
+
+/* openldap does not use this */
+#ifndef LBER_OVERFLOW
+#define LBER_OVERFLOW ((ber_tag_t) -3) /* 0xfffffffdU */
+#endif
/*
* Sequential access types
@@ -3400,6 +3525,98 @@ int slapi_re_subs( Slapi_Regex *re_handle, const char *subject, const char *src,
*/
void slapi_re_free(Slapi_Regex *re_handle);
+/* wrap non-portable LDAP API functions */
+void slapi_ldap_value_free(char **vals);
+int slapi_ldap_count_values(char **vals);
+int slapi_ldap_url_parse(const char *url, LDAPURLDesc **ludpp, int require_dn, int *secure);
+const char *slapi_urlparse_err2string(int err);
+int slapi_ldap_get_lderrno(LDAP *ld, char **m, char **s);
+#ifndef LDIF_OPT_NOWRAP
+#define LDIF_OPT_NOWRAP 0x01UL
+#endif
+#ifndef LDIF_OPT_VALUE_IS_URL
+#define LDIF_OPT_VALUE_IS_URL 0x02UL
+#endif
+#ifndef LDIF_OPT_MINIMAL_ENCODING
+#define LDIF_OPT_MINIMAL_ENCODING 0x04UL
+#endif
+void slapi_ldif_put_type_and_value_with_options( char **out, const char *t, const char *val, int vlen, unsigned long options );
+
+#if defined(USE_OPENLDAP)
+/*
+ * UTF-8 routines (should these move into libnls?)
+ */
+/* number of bytes in character */
+int ldap_utf8len( const char* );
+/* find next character */
+char *ldap_utf8next( char* );
+/* find previous character */
+char *ldap_utf8prev( char* );
+/* copy one character */
+int ldap_utf8copy( char* dst, const char* src );
+/* total number of characters */
+size_t ldap_utf8characters( const char* );
+/* get one UCS-4 character, and move *src to the next character */
+unsigned long ldap_utf8getcc( const char** src );
+/* UTF-8 aware strtok_r() */
+char *ldap_utf8strtok_r( char* src, const char* brk, char** next);
+
+/* like isalnum(*s) in the C locale */
+int ldap_utf8isalnum( char* s );
+/* like isalpha(*s) in the C locale */
+int ldap_utf8isalpha( char* s );
+/* like isdigit(*s) in the C locale */
+int ldap_utf8isdigit( char* s );
+/* like isxdigit(*s) in the C locale */
+int ldap_utf8isxdigit(char* s );
+/* like isspace(*s) in the C locale */
+int ldap_utf8isspace( char* s );
+
+#define LDAP_UTF8LEN(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8len (s) : 1)
+#define LDAP_UTF8NEXT(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8next(s) : ( s)+1)
+#define LDAP_UTF8INC(s) ((0x80 & *(unsigned char*)(s)) ? s=ldap_utf8next(s) : ++s)
+
+#define LDAP_UTF8PREV(s) ldap_utf8prev(s)
+#define LDAP_UTF8DEC(s) (s=ldap_utf8prev(s))
+
+#define LDAP_UTF8COPY(d,s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8copy(d,s) : ((*(d) = *(s)), 1))
+#define LDAP_UTF8GETCC(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8getcc (&s) : *s++)
+#define LDAP_UTF8GETC(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8getcc ((const char**)&s) : *s++)
+#endif /* USE_OPENLDAP */
+
+/* by default will allow dups */
+char **slapi_str2charray( char *str, char *brkstr );
+/*
+ * extended version of str2charray lets you disallow
+ * duplicate values into the array.
+ */
+char **slapi_str2charray_ext( char *str, char *brkstr, int allow_dups );
+
+#ifndef LDAP_PORT_MAX
+#define LDAP_PORT_MAX 65535 /* API extension */
+#endif
+
+#ifndef LDAP_ALL_USER_ATTRS
+#ifdef LDAP_ALL_USER_ATTRIBUTES
+#define LDAP_ALL_USER_ATTRS LDAP_ALL_USER_ATTRIBUTES
+#else
+#define LDAP_ALL_USER_ATTRS "*"
+#endif
+#endif
+
+#ifndef LDAP_SASL_EXTERNAL
+#define LDAP_SASL_EXTERNAL "EXTERNAL" /* TLS/SSL extension */
+#endif
+
+#ifndef LBER_SOCKET
+#ifdef LBER_SOCKET_T
+#define LBER_SOCKET LBER_SOCKET_T
+#else
+#define LBER_SOCKET int
+#endif
+#endif
+
+
#ifdef __cplusplus
}
#endif
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index ab3430a4..85c45896 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -800,8 +800,6 @@ void charray_free( char **array );
int charray_inlist( char **a, char *s );
int charray_utf8_inlist( char **a, char *s );
char ** charray_dup( char **a );
-char ** str2charray( char *str, char *brkstr );
-char ** str2charray_ext( char *str, char *brkstr, int allow_dups );
int charray_remove(char **a, const char *s, int freeit);
char ** cool_charray_dup( char **a );
void cool_charray_free( char **array );
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index 6da15a02..5b107990 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -68,9 +68,12 @@
#include "svrcore.h"
#include "fe.h"
-#include <ldap_ssl.h> /* ldapssl_client_init */
#include "certdb.h"
+#if !defined(USE_OPENLDAP)
+#include "ldap_ssl.h"
+#endif
+
/* For IRIX... */
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
@@ -1241,6 +1244,21 @@ slapd_SSL_client_auth (LDAP* ld)
"(no password). (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
errorCode, slapd_pr_strerror(errorCode));
} else {
+#if defined(USE_OPENLDAP)
+ rc = ldap_set_option(ld, LDAP_OPT_X_TLS_KEYFILE, SERVER_KEY_NAME);
+ if (rc) {
+ slapd_SSL_warn("SSL client authentication cannot be used "
+ "unable to set the key to use to %s", SERVER_KEY_NAME);
+ }
+ rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CERTFILE, cert_name);
+ if (rc) {
+ slapd_SSL_warn("SSL client authentication cannot be used "
+ "unable to set the cert to use to %s", cert_name);
+ }
+ /* not sure what else needs to be done for client auth - don't
+ currently have a way to pass in the password to use to unlock
+ the keydb - nor a way to disable caching */
+#else /* !USE_OPENLDAP */
rc = ldapssl_enable_clientauth (ld, SERVER_KEY_NAME, pw, cert_name);
if (rc != 0) {
errorCode = PR_GetError();
@@ -1258,6 +1276,7 @@ slapd_SSL_client_auth (LDAP* ld)
ldapssl_set_option(ld, SSL_NO_CACHE, PR_TRUE);
}
+#endif
}
}
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index c5a83330..12e02ce6 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -55,7 +55,7 @@
#include "slap.h"
#include "fe.h"
-LDAP_API(unsigned long) strntoul( char *from, size_t len, int base );
+unsigned long strntoul( char *from, size_t len, int base );
#define mktime_r(from) mktime (from) /* possible bug: is this thread-safe? */
static time_t currenttime;
@@ -265,7 +265,7 @@ write_localTime (time_t from, struct berval* into)
*
* Returns: See strtoul(3).
*/
-LDAP_API(unsigned long) strntoul( char *from, size_t len, int base )
+unsigned long strntoul( char *from, size_t len, int base )
{
unsigned long result;
char c = from[ len ];
diff --git a/ldap/servers/slapd/tools/ldaptool.h b/ldap/servers/slapd/tools/ldaptool.h
index e85c4d0f..1aaf0edc 100644
--- a/ldap/servers/slapd/tools/ldaptool.h
+++ b/ldap/servers/slapd/tools/ldaptool.h
@@ -100,12 +100,6 @@ extern int getopt (int argc, char *const *argv, const char *optstring);
#include <ldaplog.h>
#include <ldif.h>
-#if defined(NET_SSL)
-#include <ldap_ssl.h>
-#endif
-
-#include <ldappr.h>
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -119,7 +113,6 @@ extern "C" {
#define LDAPTOOL_DEFSEP "=" /* used by ldapcmp and ldapsearch */
#define LDAPTOOL_DEFHOST "localhost"
-#define LDAPTOOL_DEFSSLSTRENGTH LDAPSSL_AUTH_CERT
#define LDAPTOOL_DEFCERTDBPATH "."
#define LDAPTOOL_DEFKEYDBPATH "."
#define LDAPTOOL_DEFREFHOPLIMIT 5
diff --git a/ldap/servers/slapd/tools/ldclt/ldapfct.c b/ldap/servers/slapd/tools/ldclt/ldapfct.c
index e58a41e1..a2382b7f 100644
--- a/ldap/servers/slapd/tools/ldclt/ldapfct.c
+++ b/ldap/servers/slapd/tools/ldclt/ldapfct.c
@@ -256,10 +256,11 @@ dd/mm/yy | Author | Comments
#include <sasl.h>
#include "ldaptool-sasl.h"
+#if !defined(USE_OPENLDAP)
#include <ldap_ssl.h> /* ldapssl_init(), etc... */
+#endif
-
-
+#include <prprf.h>
@@ -463,7 +464,27 @@ buildNewBindDN (
+#if defined(USE_OPENLDAP)
+int
+refRebindProc(
+ LDAP *ldapCtx,
+ const char *url,
+ ber_tag_t request,
+ ber_int_t msgid,
+ void *arg
+)
+{
+ thread_context *tttctx;
+ struct berval cred;
+
+ tttctx = (thread_context *)arg;
+ cred.bv_val = tttctx->bufPasswd;
+ cred.bv_len = strlen(tttctx->bufPasswd);
+ return ldap_sasl_bind_s(ldapCtx, tttctx->bufBindDN, LDAP_SASL_SIMPLE,
+ &cred, NULL, NULL, NULL);
+}
+#else /* !USE_OPENLDAP */
/* New function */ /*JLS 08-03-01*/
/* ****************************************************************************
FUNCTION : refRebindProc
@@ -503,6 +524,7 @@ refRebindProc (
return (LDAP_SUCCESS);
}
+#endif /* !USE_OPENLDAP */
@@ -589,6 +611,7 @@ connectToServer (
int ret; /* Return value */
LBER_SOCKET fd; /* LDAP cnx's fd */
int v2v3; /* LDAP version used */
+ struct berval cred = {0, NULL};
/*
* Maybe close the connection ?
@@ -629,8 +652,8 @@ connectToServer (
if (close ((int)fd) < 0)
{
perror ("ldctx");
- printf ("ldclt[%d]: T%03d: cannot close(fd=%ld), error=%d (%s)\n",
- mctx.pid, tttctx->thrdNum, fd, errno, strerror (errno));
+ printf ("ldclt[%d]: T%03d: cannot close(fd=%d), error=%d (%s)\n",
+ mctx.pid, tttctx->thrdNum, (int)fd, errno, strerror (errno));
return (-1);
}
}
@@ -642,7 +665,7 @@ connectToServer (
* But don't be afraid, the UNBIND operation never reach the
* server that will only see a suddent socket disconnection.
*/
- ret = ldap_unbind (tttctx->ldapCtx);
+ ret = ldap_unbind_ext (tttctx->ldapCtx, NULL, NULL);
if (ret != LDAP_SUCCESS)
{
fprintf (stderr, "ldclt[%d]: T%03d: cannot ldap_unbind(), error=%d (%s)\n",
@@ -660,6 +683,27 @@ connectToServer (
*/
if (tttctx->ldapCtx == NULL)
{
+ const char *mech = LDAP_SASL_SIMPLE;
+ const char *binddn = NULL;
+ const char *passwd = NULL;
+#if defined(USE_OPENLDAP)
+ char *ldapurl = NULL;
+#endif
+
+#if defined(USE_OPENLDAP)
+ ldapurl = PR_smprintf("ldap%s://%s:%d/",
+ (mctx.mode & SSL) ? "s" : "",
+ mctx.hostname, mctx.port);
+ if ((ret = ldap_initialize(&tttctx->ldapCtx, ldapurl))) {
+ printf ("ldclt[%d]: T%03d: Cannot ldap_initialize (%s), errno=%d ldaperror=%d:%s\n",
+ mctx.pid, tttctx->thrdNum, ldapurl, errno, ret, my_ldap_err2string(ret));
+ fflush (stdout);
+ PR_smprintf_free(ldapurl);
+ return (-1);
+ }
+ PR_smprintf_free(ldapurl);
+ ldapurl = NULL;
+#else /* !USE_OPENLDAP */
/*
* SSL is enabled ?
*/
@@ -720,6 +764,18 @@ connectToServer (
return (-1);
}
}
+#endif /* !USE_OPENLDAP */
+
+ if (mctx.mode & CLTAUTH) {
+ mech = "EXTERNAL";
+ binddn = "";
+ passwd = NULL;
+ } else {
+ binddn = tttctx->bufBindDN;
+ passwd = tttctx->bufPasswd;
+ cred.bv_val = (char *)passwd;
+ cred.bv_len = strlen(passwd);
+ }
if (mctx.mode & LDAP_V2)
v2v3 = LDAP_VERSION2;
@@ -849,14 +905,21 @@ connectToServer (
perror ("malloc");
exit (LDAP_NO_MEMORY);
}
-
+#if defined(USE_OPENLDAP)
+ ret = ldap_sasl_interactive_bind_s( tttctx->ldapCtx, mctx.bindDN, mctx.sasl_mech,
+ NULL, NULL, mctx.sasl_flags,
+ ldaptool_sasl_interact, defaults );
+#else
ret = ldap_sasl_interactive_bind_ext_s( tttctx->ldapCtx, mctx.bindDN, mctx.sasl_mech,
NULL, NULL, mctx.sasl_flags,
ldaptool_sasl_interact, defaults, NULL );
+#endif
if (ret != LDAP_SUCCESS ) {
tttctx->binded = 0;
- if (!(mctx.mode & QUIET))
- ldap_perror( tttctx->ldapCtx, "Bind Error" );
+ if (!(mctx.mode & QUIET)) {
+ fprintf(stderr, "Error: could not bind: %d:%s\n",
+ ret, my_ldap_err2string(ret));
+ }
if (addErrorStat (ret) < 0)
return (-1);
} else {
@@ -868,15 +931,17 @@ connectToServer (
if (((mctx.bindDN != NULL) || (mctx.mod2 & M2_RNDBINDFILE)) && /*03-05-01*/
((!(tttctx->binded)) || (mctx.mode & BIND_EACH_OPER)))
{
+ struct berval *servercredp = NULL;
+
if (buildNewBindDN (tttctx) < 0) /*JLS 05-01-01*/
return (-1); /*JLS 05-01-01*/
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: Before ldap_simple_bind_s (%s, %s)\n",
mctx.pid, tttctx->thrdNum, tttctx->bufBindDN,
mctx.passwd?tttctx->bufPasswd:"NO PASSWORD PROVIDED");
- ret = ldap_simple_bind_s (tttctx->ldapCtx,
- tttctx->bufBindDN, /*JLS 05-01-01*/
- mctx.passwd?tttctx->bufPasswd:"NO PASSWORD PROVIDED");
+ ret = ldap_sasl_bind_s (tttctx->ldapCtx, tttctx->bufBindDN, LDAP_SASL_SIMPLE,
+ &cred, NULL, NULL, &servercredp); /*JLS 05-01-01*/
+ ber_bvfree(servercredp);
if (mctx.mode & VERY_VERBOSE)
printf ("ldclt[%d]: T%03d: After ldap_simple_bind_s (%s, %s)\n",
mctx.pid, tttctx->thrdNum, tttctx->bufBindDN,
@@ -1821,9 +1886,31 @@ createMissingNodes (
*/
if (cnx == NULL)
{
+ const char *mech = LDAP_SASL_SIMPLE;
+ const char *binddn = NULL;
+ const char *passwd = NULL;
+ struct berval cred = {0, NULL};
+#if defined(USE_OPENLDAP)
+ char *ldapurl = NULL;
+#endif
+
if (mctx.mode & VERY_VERBOSE) /*JLS 14-12-00*/
printf ("ldclt[%d]: T%03d: must connect to the server.\n",
mctx.pid, tttctx->thrdNum);
+#if defined(USE_OPENLDAP)
+ ldapurl = PR_smprintf("ldap%s://%s:%d/",
+ (mctx.mode & SSL) ? "s" : "",
+ mctx.hostname, mctx.port);
+ if ((ret = ldap_initialize(&tttctx->ldapCtx, ldapurl))) {
+ printf ("ldclt[%d]: T%03d: Cannot ldap_initialize (%s), errno=%d ldaperror=%d:%s\n",
+ mctx.pid, tttctx->thrdNum, ldapurl, errno, ret, my_ldap_err2string(ret));
+ fflush (stdout);
+ PR_smprintf_free(ldapurl);
+ return (-1);
+ }
+ PR_smprintf_free(ldapurl);
+ ldapurl = NULL;
+#else /* !USE_OPENLDAP */
/*
* SSL is enabled ?
*/
@@ -1879,6 +1966,18 @@ createMissingNodes (
return (-1);
}
}
+#endif /* !USE_OPENLDAP */
+
+ if (mctx.mode & CLTAUTH) {
+ mech = "EXTERNAL";
+ binddn = "";
+ passwd = NULL;
+ } else {
+ binddn = tttctx->bufBindDN;
+ passwd = tttctx->bufPasswd;
+ cred.bv_val = (char *)passwd;
+ cred.bv_len = strlen(passwd);
+ }
if (mctx.mode & LDAP_V2)
v2v3 = LDAP_VERSION2;
@@ -1897,30 +1996,15 @@ createMissingNodes (
/*
* Bind to the server
*/
- /*
- * for SSL client authentication, SASL BIND is used
- */
- if (mctx.mode & CLTAUTH)
- {
- ret = ldap_sasl_bind_s (tttctx->ldapCtx, "", "EXTERNAL", NULL, NULL, NULL,
+ ret = ldap_sasl_bind_s (tttctx->ldapCtx, binddn, mech, &cred, NULL, NULL,
NULL);
if (ret != LDAP_SUCCESS)
{
- printf ("ldclt[%d]: T%03d: Cannot ldap_sasl_bind_s, error=%d (%s)\n",
- mctx.pid, tttctx->thrdNum, ret, my_ldap_err2string (ret));
- fflush (stdout);
- tttctx->exitStatus = EXIT_NOBIND;
- if (addErrorStat (ret) < 0)
- return (-1);
- return (-1);
- }
- } else {
- ret = ldap_simple_bind_s (cnx, tttctx->bufBindDN, tttctx->bufPasswd);
- if (ret != LDAP_SUCCESS)
- {
- printf ("ldclt[%d]: T%03d: Cannot ldap_simple_bind_s (%s, %s), error=%d (%s)\n",
+ printf ("ldclt[%d]: T%03d: Cannot bind using mech [%s] (%s, %s), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum,
- tttctx->bufBindDN, tttctx->bufPasswd,
+ mech ? mech : "SIMPLE",
+ tttctx->bufBindDN ? tttctx->bufBindDN : "",
+ tttctx->bufPasswd ? tttctx->bufPasswd : "",
ret, my_ldap_err2string (ret));
fflush (stdout);
tttctx->exitStatus = EXIT_NOBIND; /*JLS 25-08-00*/
@@ -1929,7 +2013,6 @@ createMissingNodes (
return (-1);
}
}
- }
/*
* Create the entry
@@ -1951,7 +2034,7 @@ createMissingNodes (
* Add the entry
* If it doesn't work, we will recurse on the nodeDN
*/
- ret = ldap_add_s (cnx, nodeDN, attrs);
+ ret = ldap_add_ext_s (cnx, nodeDN, attrs, NULL, NULL);
if ((ret != LDAP_SUCCESS) && (ret != LDAP_ALREADY_EXISTS))
{
if (ret == LDAP_NO_SUCH_OBJECT)
@@ -2015,7 +2098,7 @@ createMissingNodes (
if (freeAttrib (attrs) < 0)
return (-1);
- ret = ldap_unbind (cnx);
+ ret = ldap_unbind_ext (cnx, NULL, NULL);
if (ret != LDAP_SUCCESS)
{
fprintf (stderr, "ldclt[%d]: T%03d: cannot ldap_unbind(), error=%d (%s)\n",
@@ -2775,7 +2858,7 @@ doAddEntry (
retry = 1;
while (retry)
{
- ret = ldap_add_s (tttctx->ldapCtx, newDn, attrs);
+ ret = ldap_add_ext_s (tttctx->ldapCtx, newDn, attrs, NULL, NULL);
if (ret != LDAP_SUCCESS)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
@@ -2871,6 +2954,8 @@ doAddEntry (
}
else
{
+ int msgid = 0;
+
if ((mctx.mode & VERBOSE) &&
(tttctx->asyncHit == 1) &&
(!(mctx.mode & SUPER_QUIET)))
@@ -2887,7 +2972,7 @@ doAddEntry (
if (buildNewEntry (tttctx, newDn, attrs) < 0)
return (-1);
- ret = ldap_add (tttctx->ldapCtx, newDn, attrs);
+ ret = ldap_add_ext (tttctx->ldapCtx, newDn, attrs, NULL, NULL, &msgid);
if (ret < 0)
{
if (ldap_get_option (tttctx->ldapCtx, LDAP_OPT_ERROR_NUMBER, &ret) < 0)
@@ -2929,7 +3014,7 @@ doAddEntry (
/*
* Memorize the operation
*/
- if (msgIdAdd (tttctx, ret, newDn, newDn, attrs) < 0)
+ if (msgIdAdd (tttctx, msgid, newDn, newDn, attrs) < 0)
return (-1);
if (incrementNbOpers (tttctx) < 0)
return (-1);
@@ -3160,7 +3245,7 @@ doDeleteEntry (
strcat (delDn, ",");
strcat (delDn, tttctx->bufBaseDN);
- ret = ldap_delete_s (tttctx->ldapCtx, delDn);
+ ret = ldap_delete_ext_s (tttctx->ldapCtx, delDn, NULL, NULL);
if (ret != LDAP_SUCCESS)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
@@ -3223,6 +3308,8 @@ doDeleteEntry (
}
else
{
+ int msgid = 0;
+
if ((mctx.mode & VERBOSE) &&
(tttctx->asyncHit == 1) &&
(!(mctx.mode & SUPER_QUIET)))
@@ -3243,7 +3330,7 @@ doDeleteEntry (
strcat (delDn, ",");
strcat (delDn, tttctx->bufBaseDN);
- ret = ldap_delete (tttctx->ldapCtx, delDn);
+ ret = ldap_delete_ext (tttctx->ldapCtx, delDn, NULL, NULL, &msgid);
if (ret < 0)
{
if (ldap_get_option (tttctx->ldapCtx, LDAP_OPT_ERROR_NUMBER, &ret) < 0)
@@ -3389,9 +3476,9 @@ doExactSearch (
*/
if (!(mctx.mode & ASYNC))
{
- ret = ldap_search_s (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
+ ret = ldap_search_ext_s (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
tttctx->bufFilter, attrlist, /*JLS 15-03-01*/
- mctx.attrsonly, &res); /*JLS 03-01-01*/
+ mctx.attrsonly, NULL, NULL, NULL, -1, &res); /*JLS 03-01-01*/
if (ret != LDAP_SUCCESS)
{
if (!((mctx.mode & QUIET) && ignoreError (ret)))
@@ -3493,6 +3580,8 @@ doExactSearch (
}
else
{
+ int msgid = 0;
+
if ((mctx.mode & VERBOSE) &&
(tttctx->asyncHit == 1) &&
(!(mctx.mode & SUPER_QUIET)))
@@ -3503,9 +3592,9 @@ doExactSearch (
fflush (stdout);
}
- ret = ldap_search (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
+ ret = ldap_search_ext (tttctx->ldapCtx, tttctx->bufBaseDN, mctx.scope,
tttctx->bufFilter, attrlist, /*JLS 15-03-01*/
- mctx.attrsonly); /*JLS 03-01-01*/
+ mctx.attrsonly, NULL, NULL, NULL, -1, &msgid); /*JLS 03-01-01*/
if (ret < 0)
{
if (ldap_get_option (tttctx->ldapCtx, LDAP_OPT_ERROR_NUMBER, &ret) < 0)
@@ -3699,7 +3788,7 @@ doAbandon (thread_context *tttctx)
if (msgid >= 0)
{
/* ABANDON the search request immediately */
- (void) ldap_abandon(tttctx->ldapCtx, msgid);
+ (void) ldap_abandon_ext(tttctx->ldapCtx, msgid, NULL, NULL);
}
/*
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.c b/ldap/servers/slapd/tools/ldclt/ldclt.c
index 5346e241..f98233cc 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.c
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.c
@@ -281,7 +281,9 @@ dd/mm/yy | Author | Comments
#include <time.h> /* ctime(), etc... */ /*JLS 18-08-00*/
#include <lber.h> /* ldap C-API BER decl. */
#include <ldap.h> /* ldap C-API decl. */
+#if !defined(USE_OPENLDAP)
#include <ldap_ssl.h> /* ldapssl_init(), etc... */
+#endif
#ifdef LDAP_H_FROM_QA_WKA
#include <proto-ldap.h> /* ldap C-API prototypes */
#endif
@@ -1547,6 +1549,7 @@ basicInit (void)
}
}
+#if !defined(USE_OPENLDAP)
/*
* SSL is enabled ?
*/
@@ -1577,6 +1580,7 @@ basicInit (void)
}
}
}
+#endif /* !defined(USE_OPENLDAP) */
/*
* Specific scenarios initialization...
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.h b/ldap/servers/slapd/tools/ldclt/ldclt.h
index 0ed8ef8e..8fa03d8b 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.h
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.h
@@ -327,20 +327,54 @@ dd/mm/yy | Author | Comments
#ifdef SOLARIS_LIBLDAP /*JLS 19-09-00*/
#define WORKAROUND_4197228 1 /*JLS 19-09-00*/
#else /*JLS 19-09-00*/
+#ifndef LDAP_REQ_BIND
#define LDAP_REQ_BIND 0x60 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_UNBIND
#define LDAP_REQ_UNBIND 0x42 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_SEARCH
#define LDAP_REQ_SEARCH 0x63 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_MODIFY
#define LDAP_REQ_MODIFY 0x66 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_ADD
#define LDAP_REQ_ADD 0x68 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_DELETE
#define LDAP_REQ_DELETE 0x4a /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_MODRDN
#define LDAP_REQ_MODRDN 0x6c /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_COMPARE
#define LDAP_REQ_COMPARE 0x6e /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_ABANDON
#define LDAP_REQ_ABANDON 0x50 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_EXTENDED
#define LDAP_REQ_EXTENDED 0x77 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_UNBIND_30
#define LDAP_REQ_UNBIND_30 0x62 /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_DELETE_30
#define LDAP_REQ_DELETE_30 0x6a /*JLS 19-09-00*/
+#endif
+#ifndef LDAP_REQ_ABANDON_30
#define LDAP_REQ_ABANDON_30 0x70 /*JLS 19-09-00*/
#endif /*JLS 19-09-00*/
+#endif
+
+#ifndef LBER_SOCKET
+#ifdef LBER_SOCKET_T
+#define LBER_SOCKET LBER_SOCKET_T
+#else
+#define LBER_SOCKET int
+#endif
+#endif
/*
* This structure is the internal representation of an image
diff --git a/ldap/servers/slapd/tools/ldclt/scalab01.c b/ldap/servers/slapd/tools/ldclt/scalab01.c
index 3dc2bda8..595df0ff 100644
--- a/ldap/servers/slapd/tools/ldclt/scalab01.c
+++ b/ldap/servers/slapd/tools/ldclt/scalab01.c
@@ -91,8 +91,10 @@ dd/mm/yy | Author | Comments
#include <lber.h> /* ldap C-API BER declarations */
#include <ldap.h> /* ldap C-API declarations */
+#if !defined(USE_OPENLDAP)
#include <ldap_ssl.h> /* ldapssl_init(), etc... */
-
+#endif
+#include <prprf.h>
#include "port.h" /* Portability definitions */
#include "ldclt.h" /* This tool's include file */
#include "utils.h" /* Utilities functions */
@@ -509,8 +511,28 @@ scalab01_connectSuperuser (void)
{
int ret; /* Return value */
int v2v3; /* LDAP version used */
- char bindDN [MAX_DN_LENGTH]; /* To bind */
+ char bindDN [MAX_DN_LENGTH] = {0}; /* To bind */
+ const char *mech = LDAP_SASL_SIMPLE;
+ struct berval cred = {0, NULL};
+ struct berval *servercredp = NULL;
+#if defined(USE_OPENLDAP)
+ char *ldapurl = NULL;
+#endif
+#if defined(USE_OPENLDAP)
+ ldapurl = PR_smprintf("ldap%s://%s:%d/",
+ (mctx.mode & SSL) ? "s" : "",
+ mctx.hostname, mctx.port);
+ if ((ret = ldap_initialize(&s1ctx.ldapCtx, ldapurl))) {
+ printf ("ldclt[%d]: ctrl: Cannot ldap_initialize (%s), errno=%d ldaperror=%d:%s\n",
+ mctx.pid, ldapurl, errno, ret, my_ldap_err2string(ret));
+ fflush (stdout);
+ PR_smprintf_free(ldapurl);
+ return (-1);
+ }
+ PR_smprintf_free(ldapurl);
+ ldapurl = NULL;
+#else /* !USE_OPENLDAP */
/*
* Create the LDAP context
*/
@@ -571,6 +593,17 @@ scalab01_connectSuperuser (void)
return (-1);
}
}
+#endif /* !USE_OPENLDAP */
+
+ if (mctx.mode & CLTAUTH) {
+ mech = "EXTERNAL";
+ } else {
+ strcpy (bindDN, SCALAB01_SUPER_USER_RDN);
+ strcat (bindDN, ",");
+ strcat (bindDN, mctx.baseDN);
+ cred.bv_val = SCALAB01_SUPER_USER_PASSWORD;
+ cred.bv_len = strlen(cred.bv_val);
+ }
/*
* Set the LDAP version and other options...
@@ -590,49 +623,21 @@ scalab01_connectSuperuser (void)
} /*JLS 14-03-01*/
- /*
- * Now we could bind
- */
- /*
- * for SSL client authentication, SASL BIND is used
- */
- if (mctx.mode & CLTAUTH)
- {
- if (mctx.mode & VERY_VERBOSE)
- printf ("ldclt[%d]: ctrl: Before ldap_sasl_bind_s\n", mctx.pid);
- ret = ldap_sasl_bind_s (s1ctx.ldapCtx, "", "EXTERNAL", NULL, NULL, NULL,
- NULL);
- if (mctx.mode & VERY_VERBOSE)
- printf ("ldclt[%d]: ctrl: After ldap_sasl_bind_s\n", mctx.pid);
- if (ret != LDAP_SUCCESS)
- {
- printf ("ldclt[%d]: ctrl: Cannot ldap_sasl_bind_s, error=%d (%s)\n",
- mctx.pid, ret, my_ldap_err2string (ret));
- fflush (stdout);
- return (-1);
- }
- }
- else
+ if (mctx.mode & VERY_VERBOSE)
+ printf ("ldclt[%d]: ctrl: Before bind mech %s (%s , %s)\n",
+ mctx.pid, mech ? mech : "SIMPLE", bindDN, SCALAB01_SUPER_USER_PASSWORD);
+ ret = ldap_sasl_bind_s (s1ctx.ldapCtx, bindDN, mech, &cred, NULL, NULL, &servercredp);
+ ber_bvfree(servercredp);
+ if (mctx.mode & VERY_VERBOSE)
+ printf ("ldclt[%d]: ctrl: After bind mech %s (%s, %s)\n",
+ mctx.pid, mech ? mech : "SIMPLE", bindDN, SCALAB01_SUPER_USER_PASSWORD);
+ if (ret != LDAP_SUCCESS)
{
- strcpy (bindDN, SCALAB01_SUPER_USER_RDN);
- strcat (bindDN, ",");
- strcat (bindDN, mctx.baseDN);
- if (mctx.mode & VERY_VERBOSE)
- printf ("ldclt[%d]: ctrl: Before ldap_simple_bind_s (%s , %s)\n",
- mctx.pid, bindDN, SCALAB01_SUPER_USER_PASSWORD);
- ret = ldap_simple_bind_s (s1ctx.ldapCtx,
- bindDN, SCALAB01_SUPER_USER_PASSWORD);
- if (mctx.mode & VERY_VERBOSE)
- printf ("ldclt[%d]: ctrl: After ldap_simple_bind_s (%s, %s)\n",
- mctx.pid, bindDN, SCALAB01_SUPER_USER_PASSWORD);
- if (ret != LDAP_SUCCESS)
- {
- printf("ldclt[%d]: ctrl: Cannot ldap_simple_bind_s (%s, %s), error=%d (%s)\n",
- mctx.pid, bindDN, SCALAB01_SUPER_USER_PASSWORD,
- ret, my_ldap_err2string (ret));
- fflush (stdout);
- return (-1);
- }
+ printf("ldclt[%d]: ctrl: Cannot bind mech %s (%s, %s), error=%d (%s)\n",
+ mctx.pid, mech ? mech : "SIMPLE", bindDN, SCALAB01_SUPER_USER_PASSWORD,
+ ret, my_ldap_err2string (ret));
+ fflush (stdout);
+ return (-1);
}
/*
@@ -676,7 +681,6 @@ readAttrValue (
LDAPMessage *cur; /* Current message */
BerElement *ber; /* To decode the response */
char *aname; /* Current attribute name */
- char **vals; /* Attribute value returned */
char *filter; /* Filter used for searching */
/*
@@ -686,8 +690,8 @@ readAttrValue (
attrs[1] = NULL;
filter = (char *)malloc((4+strlen(attname))*sizeof(char));
sprintf(filter, "(%s=*)", attname);
- ret = ldap_search_s (ldapCtx, dn, LDAP_SCOPE_BASE,
- filter, attrs, 0, &res);
+ ret = ldap_search_ext_s (ldapCtx, dn, LDAP_SCOPE_BASE,
+ filter, attrs, 0, NULL, NULL, NULL, -1, &res);
if (filter != NULL) free(filter);
if (ret != LDAP_SUCCESS)
{
@@ -712,7 +716,8 @@ readAttrValue (
*/
if (!strcmp (aname, attname))
{
- vals = ldap_get_values (ldapCtx, cur, aname);
+ struct berval **vals;
+ vals = ldap_get_values_len (ldapCtx, cur, aname);
if (vals == NULL)
{
printf ("ldclt[%d]: %s: no value for %s in %s\n",
@@ -720,8 +725,9 @@ readAttrValue (
fflush (stdout);
return (-1);
}
- strcpy (value, vals[0]);
- ldap_value_free (vals);
+ strncpy (value, vals[0]->bv_val, vals[0]->bv_len);
+ value[vals[0]->bv_len] = '\0';
+ ldap_value_free_len (vals);
}
/*
@@ -736,7 +742,7 @@ readAttrValue (
* Next entry - shouldn't happen in theory
*/
if (ber != NULL)
- ldap_ber_free (ber, 0);
+ ber_free (ber, 0);
cur = ldap_next_entry (ldapCtx, cur);
}
ldap_msgfree (res); /* Free the response */
diff --git a/ldap/servers/slapd/tools/ldif.c b/ldap/servers/slapd/tools/ldif.c
index bf100539..892b6ee2 100644
--- a/ldap/servers/slapd/tools/ldif.c
+++ b/ldap/servers/slapd/tools/ldif.c
@@ -42,6 +42,7 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <memory.h>
#include <sys/types.h>
#if defined( _WINDOWS ) || defined( _WIN32 )
@@ -58,6 +59,24 @@
int ldap_syslog;
int ldap_syslog_level;
+#if defined(USE_OPENLDAP)
+static char *
+ldif_type_and_value(const char *type, const char *val, int vlen)
+{
+ char *buf, *p;
+ int tlen;
+
+ tlen = strlen( type );
+ if (( buf = (char *)malloc( LDIF_SIZE_NEEDED( tlen, vlen ) + 1 )) !=
+ NULL ) {
+ p = buf;
+ ldif_sput( &p, LDIF_PUT_VALUE, type, val, vlen );
+ *p = '\0';
+ }
+
+ return( buf );
+}
+#endif
static void
display_usage( char *name )
diff --git a/ldap/servers/slapd/tools/pwenc.c b/ldap/servers/slapd/tools/pwenc.c
index dba107a3..c03cfdec 100644
--- a/ldap/servers/slapd/tools/pwenc.c
+++ b/ldap/servers/slapd/tools/pwenc.c
@@ -61,7 +61,6 @@
#include <ctype.h>
#include <stdlib.h>
#include "ldap.h"
-#include "ldif.h"
#include "../slapi-plugin.h"
#include "../slap.h"
#include <nspr.h>
diff --git a/ldap/servers/slapd/tools/rsearch/addthread.c b/ldap/servers/slapd/tools/rsearch/addthread.c
index d87c5a53..417a4c19 100644
--- a/ldap/servers/slapd/tools/rsearch/addthread.c
+++ b/ldap/servers/slapd/tools/rsearch/addthread.c
@@ -53,6 +53,13 @@
#include "addthread.h"
#include "infadd.h"
+#ifndef LBER_SOCKET
+#ifdef LBER_SOCKET_T
+#define LBER_SOCKET LBER_SOCKET_T
+#else
+#define LBER_SOCKET int
+#endif
+#endif
/* local data for a search thread */
struct _addthread {
diff --git a/ldap/servers/slapd/tools/rsearch/searchthread.c b/ldap/servers/slapd/tools/rsearch/searchthread.c
index 443419c0..38d5d593 100644
--- a/ldap/servers/slapd/tools/rsearch/searchthread.c
+++ b/ldap/servers/slapd/tools/rsearch/searchthread.c
@@ -57,6 +57,14 @@
#include "rsearch.h"
#include "searchthread.h"
+#ifndef LBER_SOCKET
+#ifdef LBER_SOCKET_T
+#define LBER_SOCKET LBER_SOCKET_T
+#else
+#define LBER_SOCKET int
+#endif
+#endif
+
/* local data for a search thread */
struct _searchthread {
PRUint32 searchCount;
diff --git a/ldap/servers/slapd/utf8.c b/ldap/servers/slapd/utf8.c
new file mode 100644
index 00000000..df092024
--- /dev/null
+++ b/ldap/servers/slapd/utf8.c
@@ -0,0 +1,310 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * END COPYRIGHT BLOCK **/
+/* ***** BEGIN LICENSE BLOCK *****
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * June 25, 2009 - copied from Mozilla LDAP C SDK - relicensed to use GPLv2
+ * with directory server plug-in exception as per the above paragraph
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* the openldap library has utf8 string handling functions, but they
+ are somewhat different, and not exposed/exported for use outside
+ of the library - therefore, we just copy these from mozldap when
+ using openldap
+*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(USE_OPENLDAP)
+
+/* uft8.c - misc. utf8 "string" functions. */
+#include "slapi-plugin.h"
+
+static char UTF8len[64]
+= {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6};
+
+int
+ldap_utf8len (const char* s)
+ /* Return the number of char's in the character at *s. */
+{
+ return ldap_utf8next((char*)s) - s;
+}
+
+char*
+ldap_utf8next (char* s)
+ /* Return a pointer to the character immediately following *s.
+ Handle any valid UTF-8 character, including '\0' and ASCII.
+ Try to handle a misaligned pointer or a malformed character.
+ */
+{
+ register unsigned char* next = (unsigned char*)s;
+ switch (UTF8len [(*next >> 2) & 0x3F]) {
+ case 0: /* erroneous: s points to the middle of a character. */
+ case 6: if ((*++next & 0xC0) != 0x80) break;
+ case 5: if ((*++next & 0xC0) != 0x80) break;
+ case 4: if ((*++next & 0xC0) != 0x80) break;
+ case 3: if ((*++next & 0xC0) != 0x80) break;
+ case 2: if ((*++next & 0xC0) != 0x80) break;
+ case 1: ++next;
+ }
+ return (char*) next;
+}
+
+char*
+ldap_utf8prev (char* s)
+ /* Return a pointer to the character immediately preceding *s.
+ Handle any valid UTF-8 character, including '\0' and ASCII.
+ Try to handle a misaligned pointer or a malformed character.
+ */
+{
+ register unsigned char* prev = (unsigned char*)s;
+ unsigned char* limit = prev - 6;
+ while (((*--prev & 0xC0) == 0x80) && (prev != limit)) {
+ ;
+ }
+ return (char*) prev;
+}
+
+int
+ldap_utf8copy (char* dst, const char* src)
+ /* Copy a character from src to dst; return the number of char's copied.
+ Handle any valid UTF-8 character, including '\0' and ASCII.
+ Try to handle a misaligned pointer or a malformed character.
+ */
+{
+ register const unsigned char* s = (const unsigned char*)src;
+ switch (UTF8len [(*s >> 2) & 0x3F]) {
+ case 0: /* erroneous: s points to the middle of a character. */
+ case 6: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
+ case 5: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
+ case 4: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
+ case 3: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
+ case 2: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
+ case 1: *dst = *s++;
+ }
+ return s - (const unsigned char*)src;
+}
+
+size_t
+ldap_utf8characters (const char* src)
+ /* Return the number of UTF-8 characters in the 0-terminated array s. */
+{
+ register char* s = (char*)src;
+ size_t n;
+ for (n = 0; *s; LDAP_UTF8INC(s)) ++n;
+ return n;
+}
+
+unsigned long
+ldap_utf8getcc( const char** src )
+{
+ register unsigned long c = 0;
+ register const unsigned char* s = (const unsigned char*)*src;
+ switch (UTF8len [(*s >> 2) & 0x3F]) {
+ case 0: /* erroneous: s points to the middle of a character. */
+ c = (*s++) & 0x3F; goto more5;
+ case 1: c = (*s++); break;
+ case 2: c = (*s++) & 0x1F; goto more1;
+ case 3: c = (*s++) & 0x0F; goto more2;
+ case 4: c = (*s++) & 0x07; goto more3;
+ case 5: c = (*s++) & 0x03; goto more4;
+ case 6: c = (*s++) & 0x01; goto more5;
+ more5: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
+ more4: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
+ more3: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
+ more2: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
+ more1: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
+ break;
+ }
+ *src = (const char*)s;
+ return c;
+}
+
+char*
+ldap_utf8strtok_r( char* sp, const char* brk, char** next)
+{
+ const char *bp;
+ unsigned long sc, bc;
+ char *tok;
+
+ if (sp == NULL && (sp = *next) == NULL)
+ return NULL;
+
+ /* Skip leading delimiters; roughly, sp += strspn(sp, brk) */
+ cont:
+ sc = LDAP_UTF8GETC(sp);
+ for (bp = brk; (bc = LDAP_UTF8GETCC(bp)) != 0;) {
+ if (sc == bc)
+ goto cont;
+ }
+
+ if (sc == 0) { /* no non-delimiter characters */
+ *next = NULL;
+ return NULL;
+ }
+ tok = LDAP_UTF8PREV(sp);
+
+ /* Scan token; roughly, sp += strcspn(sp, brk)
+ * Note that brk must be 0-terminated; we stop if we see that, too.
+ */
+ while (1) {
+ sc = LDAP_UTF8GETC(sp);
+ bp = brk;
+ do {
+ if ((bc = LDAP_UTF8GETCC(bp)) == sc) {
+ if (sc == 0) {
+ *next = NULL;
+ } else {
+ *next = sp;
+ *(LDAP_UTF8PREV(sp)) = 0;
+ }
+ return tok;
+ }
+ } while (bc != 0);
+ }
+ /* NOTREACHED */
+}
+
+int
+ldap_utf8isalnum( char* s )
+{
+ register unsigned char c = *(unsigned char*)s;
+ if (0x80 & c) return 0;
+ if (c >= 'A' && c <= 'Z') return 1;
+ if (c >= 'a' && c <= 'z') return 1;
+ if (c >= '0' && c <= '9') return 1;
+ return 0;
+}
+
+int
+ldap_utf8isalpha( char* s )
+{
+ register unsigned char c = *(unsigned char*)s;
+ if (0x80 & c) return 0;
+ if (c >= 'A' && c <= 'Z') return 1;
+ if (c >= 'a' && c <= 'z') return 1;
+ return 0;
+}
+
+int
+ldap_utf8isdigit( char* s )
+{
+ register unsigned char c = *(unsigned char*)s;
+ if (0x80 & c) return 0;
+ if (c >= '0' && c <= '9') return 1;
+ return 0;
+}
+
+int
+ldap_utf8isxdigit( char* s )
+{
+ register unsigned char c = *(unsigned char*)s;
+ if (0x80 & c) return 0;
+ if (c >= '0' && c <= '9') return 1;
+ if (c >= 'A' && c <= 'F') return 1;
+ if (c >= 'a' && c <= 'f') return 1;
+ return 0;
+}
+
+int
+ldap_utf8isspace( char* s )
+{
+ register unsigned char *c = (unsigned char*)s;
+ int len = ldap_utf8len(s);
+
+ if (len == 0) {
+ return 0;
+ } else if (len == 1) {
+ switch (*c) {
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ case 0x0C:
+ case 0x0D:
+ case 0x20:
+ return 1;
+ default:
+ return 0;
+ }
+ } else if (len == 2) {
+ if (*c == 0xc2) {
+ return *(c+1) == 0x80;
+ }
+ } else if (len == 3) {
+ if (*c == 0xE2) {
+ c++;
+ if (*c == 0x80) {
+ c++;
+ return (*c>=0x80 && *c<=0x8a);
+ }
+ } else if (*c == 0xE3) {
+ return (*(c+1)==0x80) && (*(c+2)==0x80);
+ } else if (*c==0xEF) {
+ return (*(c+1)==0xBB) && (*(c+2)==0xBF);
+ }
+ return 0;
+ }
+
+ /* should never reach here */
+ return 0;
+}
+
+#endif /* USE_OPENLDAP */
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index 672eff1d..2f55ee49 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -55,8 +55,6 @@
#include "prtime.h"
#include "prinrval.h"
#include "snmp_collator.h"
-#include <ldap_ssl.h>
-#include <ldappr.h>
#define UTIL_ESCAPE_NONE 0
#define UTIL_ESCAPE_HEX 1
@@ -836,1235 +834,3 @@ slapd_comp_path(char *p0, char *p1)
slapi_ch_free_string(&norm_p1);
return rval;
}
-
-#ifdef MEMPOOL_EXPERIMENTAL
-void _free_wrapper(void *ptr)
-{
- slapi_ch_free(&ptr);
-}
-#endif
-
-/*
- * Function: slapi_ldap_unbind()
- * Purpose: release an LDAP session obtained from a call to slapi_ldap_init().
- */
-void
-slapi_ldap_unbind( LDAP *ld )
-{
- if ( ld != NULL ) {
- ldap_unbind( ld );
- }
-}
-
-const char *
-slapi_urlparse_err2string( int err )
-{
- const char *s="internal error";
-
- switch( err ) {
- case 0:
- s = "no error";
- break;
- case LDAP_URL_ERR_NOTLDAP:
- s = "missing ldap:// or ldaps:// or ldapi://";
- break;
- case LDAP_URL_ERR_NODN:
- s = "missing suffix";
- break;
- case LDAP_URL_ERR_BADSCOPE:
- s = "invalid search scope";
- break;
- case LDAP_URL_ERR_MEM:
- s = "unable to allocate memory";
- break;
- case LDAP_URL_ERR_PARAM:
- s = "bad parameter to an LDAP URL function";
- break;
- }
-
- return( s );
-}
-
-#include <sasl.h>
-
-/*
- Perform LDAP init and return an LDAP* handle. If ldapurl is given,
- that is used as the basis for the protocol, host, port, and whether
- to use starttls (given on the end as ldap://..../?????starttlsOID
- If hostname is given, LDAP or LDAPS is assumed, and this will override
- the hostname from the ldapurl, if any. If port is > 0, this is the
- port number to use. It will override the port in the ldapurl, if any.
- If no port is given in port or ldapurl, the default will be used based
- on the secure setting (389 for ldap, 636 for ldaps, 389 for starttls)
- secure takes 1 of 3 values - 0 means regular ldap, 1 means ldaps, 2
- means regular ldap with starttls.
- filename is the ldapi file name - if this is given, and no other options
- are given, ldapi is assumed.
- */
-/* util_sasl_path: the string argument for putenv.
- It must be a global or a static */
-char util_sasl_path[MAXPATHLEN];
-
-LDAP *
-slapi_ldap_init_ext(
- const char *ldapurl, /* full ldap url */
- const char *hostname, /* can also use this to override
- host in url */
- int port, /* can also use this to override port in url */
- int secure, /* 0 for ldap, 1 for ldaps, 2 for starttls -
- override proto in url */
- int shared, /* if true, LDAP* will be shared among multiple threads */
- const char *filename /* for ldapi */
-)
-{
- LDAPURLDesc *ludp = NULL;
- LDAP *ld = NULL;
- int rc = 0;
-
- /* We need to provide a sasl path used for client connections, especially
- if the server is not set up to be a sasl server - since mozldap provides
- no way to override the default path programatically, we set the sasl
- path to the environment variable SASL_PATH. */
- char *configpluginpath = config_get_saslpath();
- char *pluginpath = configpluginpath;
- char *pp = NULL;
-
- if (NULL == pluginpath || (*pluginpath == '\0')) {
- slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_init_ext",
- "configpluginpath == NULL\n");
- if (!(pluginpath = getenv("SASL_PATH"))) {
-#if defined(LINUX) && defined(__LP64__)
- pluginpath = "/usr/lib64/sasl2";
-#else
- pluginpath = "/usr/lib/sasl2";
-#endif
- }
- }
- if ('\0' == util_sasl_path[0] || /* first time */
- NULL == (pp = strchr(util_sasl_path, '=')) || /* invalid arg for putenv */
- (0 != strcmp(++pp, pluginpath)) /* sasl_path has been updated */ ) {
- PR_snprintf(util_sasl_path, sizeof(util_sasl_path),
- "SASL_PATH=%s", pluginpath);
- slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_init_ext",
- "putenv(%s)\n", util_sasl_path);
- putenv(util_sasl_path);
- }
- slapi_ch_free_string(&configpluginpath);
-
- /* if ldapurl is given, parse it */
- if (ldapurl && ((rc = ldap_url_parse_no_defaults(ldapurl, &ludp, 0)) ||
- !ludp)) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "Could not parse given LDAP URL [%s] : error [%s]\n",
- ldapurl ? ldapurl : "NULL",
- slapi_urlparse_err2string(rc));
- goto done;
- }
-
- /* use url host if no host given */
- if (!hostname && ludp && ludp->lud_host) {
- hostname = ludp->lud_host;
- }
-
- /* use url port if no port given */
- if (!port && ludp && ludp->lud_port) {
- port = ludp->lud_port;
- }
-
- /* use secure setting from url if none given */
- if (!secure && ludp) {
- if (ludp->lud_options & LDAP_URL_OPT_SECURE) {
- secure = 1;
- } else if (0/* starttls option - not supported yet in LDAP URLs */) {
- secure = 2;
- }
- }
-
- /* ldap_url_parse doesn't yet handle ldapi */
- /*
- if (!filename && ludp && ludp->lud_file) {
- filename = ludp->lud_file;
- }
- */
-
-#ifdef MEMPOOL_EXPERIMENTAL
- {
- /*
- * slapi_ch_malloc functions need to be set to LDAP C SDK
- */
- struct ldap_memalloc_fns memalloc_fns;
- memalloc_fns.ldapmem_malloc = (LDAP_MALLOC_CALLBACK *)slapi_ch_malloc;
- memalloc_fns.ldapmem_calloc = (LDAP_CALLOC_CALLBACK *)slapi_ch_calloc;
- memalloc_fns.ldapmem_realloc = (LDAP_REALLOC_CALLBACK *)slapi_ch_realloc;
- memalloc_fns.ldapmem_free = (LDAP_FREE_CALLBACK *)_free_wrapper;
- }
- /*
- * MEMPOOL_EXPERIMENTAL:
- * These LDAP C SDK init function needs to be revisited.
- * In ldap_init called via ldapssl_init and prldap_init initializes
- * options and set default values including memalloc_fns, then it
- * initializes as sasl client by calling sasl_client_init. In
- * sasl_client_init, it creates mechlist using the malloc function
- * available at the moment which could mismatch the malloc/free functions
- * set later.
- */
-#endif
- if (filename) {
- /* ldapi in mozldap client is not yet supported */
- } else if (secure == 1) {
- ld = ldapssl_init(hostname, port, secure);
- } else { /* regular ldap and/or starttls */
- /*
- * Leverage the libprldap layer to take care of all the NSPR
- * integration.
- * Note that ldapssl_init() uses libprldap implicitly.
- */
- ld = prldap_init(hostname, port, shared);
- }
-
- /* Update snmp interaction table */
- if (hostname) {
- if (ld == NULL) {
- set_snmp_interaction_row((char *)hostname, port, -1);
- } else {
- set_snmp_interaction_row((char *)hostname, port, 0);
- }
- }
-
- if ((ld != NULL) && !filename) {
- /*
- * Set the outbound LDAP I/O timeout based on the server config.
- */
- int io_timeout_ms = config_get_outbound_ldap_io_timeout();
- if (io_timeout_ms > 0) {
- if (prldap_set_session_option(ld, NULL, PRLDAP_OPT_IO_MAX_TIMEOUT,
- io_timeout_ms) != LDAP_SUCCESS) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "failed: unable to set outbound I/O "
- "timeout to %dms\n",
- io_timeout_ms);
- slapi_ldap_unbind(ld);
- ld = NULL;
- goto done;
- }
- }
-
- /*
- * Set SSL strength (server certificate validity checking).
- */
- if (secure > 0) {
- int ssl_strength = 0;
- LDAP *myld = NULL;
-
- if (config_get_ssl_check_hostname()) {
- /* check hostname against name in certificate */
- ssl_strength = LDAPSSL_AUTH_CNCHECK;
- } else {
- /* verify certificate only */
- ssl_strength = LDAPSSL_AUTH_CERT;
- }
-
- /* we can only use the set functions below with a real
- LDAP* if it has already gone through ldapssl_init -
- so, use NULL if using starttls */
- if (secure == 1) {
- myld = ld;
- }
-
- if ((rc = ldapssl_set_strength(myld, ssl_strength)) ||
- (rc = ldapssl_set_option(myld, SSL_ENABLE_SSL2, PR_FALSE)) ||
- (rc = ldapssl_set_option(myld, SSL_ENABLE_SSL3, PR_TRUE)) ||
- (rc = ldapssl_set_option(myld, SSL_ENABLE_TLS, PR_TRUE))) {
- int prerr = PR_GetError();
-
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_init_ext",
- "failed: unable to set SSL options ("
- SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- prerr, slapd_pr_strerror(prerr));
-
- }
- if (secure == 1) {
- /* tell bind code we are using SSL */
- ldap_set_option(ld, LDAP_OPT_SSL, LDAP_OPT_ON);
- }
- }
- }
-
- if (ld && (secure == 2)) {
- /* We don't have a way to stash context data with the LDAP*, so we
- stash the information in the client controls (currently unused).
- We don't want to open the connection in ldap_init, since that's
- not the semantic - the connection is not usually opened until
- the first operation is sent, which is usually the bind - or
- in this case, the start_tls - so we stash the start_tls so
- we can do it in slapi_ldap_bind - note that this will get
- cleaned up when the LDAP* is disposed of
- */
- LDAPControl start_tls_dummy_ctrl;
- LDAPControl **clientctrls = NULL;
-
- /* returns copy of controls */
- ldap_get_option(ld, LDAP_OPT_CLIENT_CONTROLS, &clientctrls);
-
- start_tls_dummy_ctrl.ldctl_oid = slapi_ch_strdup(START_TLS_OID);
- start_tls_dummy_ctrl.ldctl_value.bv_val = NULL;
- start_tls_dummy_ctrl.ldctl_value.bv_len = 0;
- start_tls_dummy_ctrl.ldctl_iscritical = 0;
- slapi_add_control_ext(&clientctrls, &start_tls_dummy_ctrl, 1);
- /* set option frees old list and copies the new list */
- ldap_set_option(ld, LDAP_OPT_CLIENT_CONTROLS, clientctrls);
- ldap_controls_free(clientctrls); /* free the copy */
- }
-
- slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_init_ext",
- "Success: set up conn to [%s:%d]%s\n",
- hostname, port,
- (secure == 2) ? " using startTLS" :
- ((secure == 1) ? " using SSL" : ""));
-done:
- ldap_free_urldesc(ludp);
-
- return( ld );
-}
-
-/*
- * Function: slapi_ldap_init()
- * Description: just like ldap_ssl_init() but also arranges for the LDAP
- * session handle returned to be safely shareable by multiple threads
- * if "shared" is non-zero.
- * Returns:
- * an LDAP session handle (NULL if some local error occurs).
- */
-LDAP *
-slapi_ldap_init( char *ldaphost, int ldapport, int secure, int shared )
-{
- return slapi_ldap_init_ext(NULL, ldaphost, ldapport, secure, shared, NULL);
-}
-
-/*
- * Does the correct bind operation simple/sasl/cert depending
- * on the arguments passed in. If the user specified to use
- * starttls in init, this will do the starttls first. If using
- * ssl or client cert auth, this will initialize the client side
- * of that.
- */
-int
-slapi_ldap_bind(
- LDAP *ld, /* ldap connection */
- const char *bindid, /* usually a bind DN for simple bind */
- const char *creds, /* usually a password for simple bind */
- const char *mech, /* name of mechanism */
- LDAPControl **serverctrls, /* additional controls to send */
- LDAPControl ***returnedctrls, /* returned controls */
- struct timeval *timeout, /* timeout */
- int *msgidp /* pass in non-NULL for async handling */
-)
-{
- int rc = LDAP_SUCCESS;
- LDAPControl **clientctrls = NULL;
- int secure = 0;
- struct berval bvcreds = {0, NULL};
- LDAPMessage *result = NULL;
- struct berval *servercredp = NULL;
-
- /* do starttls if requested
- NOTE - starttls is an extop, not a control, but we don't have
- a place we can stash this information in the LDAP*, other
- than the currently unused clientctrls */
- ldap_get_option(ld, LDAP_OPT_CLIENT_CONTROLS, &clientctrls);
- if (clientctrls && clientctrls[0] &&
- slapi_control_present(clientctrls, START_TLS_OID, NULL, NULL)) {
- secure = 2;
- } else {
- ldap_get_option(ld, LDAP_OPT_SSL, &secure);
- }
-
- if ((secure > 0) && mech && !strcmp(mech, LDAP_SASL_EXTERNAL)) {
- /* SSL connections will use the server's security context
- and cert for client auth */
- rc = slapd_SSL_client_auth(ld);
-
- if (rc != 0) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: could not configure the server for cert "
- "auth - error %d - make sure the server is "
- "correctly configured for SSL/TLS\n", rc);
- goto done;
- } else {
- slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
- "Set up conn to use client auth\n");
- }
- bvcreds.bv_val = NULL; /* ignore username and passed in creds */
- bvcreds.bv_len = 0; /* for external auth */
- bindid = NULL;
- } else { /* other type of auth */
- bvcreds.bv_val = (char *)creds;
- bvcreds.bv_len = creds ? strlen(creds) : 0;
- }
-
- if (secure == 2) { /* send start tls */
- rc = ldap_start_tls_s(ld, NULL /* serverctrls?? */, NULL);
- if (LDAP_SUCCESS != rc) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: could not send startTLS request: "
- "error %d (%s)\n",
- rc, ldap_err2string(rc));
- goto done;
- }
- slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
- "startTLS started on connection\n");
- }
-
- /* The connection has been set up - now do the actual bind, depending on
- the mechanism and arguments */
- if (!mech || (mech == LDAP_SASL_SIMPLE) ||
- !strcmp(mech, LDAP_SASL_EXTERNAL)) {
- int mymsgid = 0;
-
- slapi_log_error(SLAPI_LOG_SHELL, "slapi_ldap_bind",
- "attempting %s bind with id [%s] creds [%s]\n",
- mech ? mech : "SIMPLE",
- bindid, creds);
- if ((rc = ldap_sasl_bind(ld, bindid, mech, &bvcreds, serverctrls,
- NULL /* clientctrls */, &mymsgid))) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: could not send bind request for id "
- "[%s] mech [%s]: error %d (%s) %d (%s) %d (%s)\n",
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE",
- rc, ldap_err2string(rc),
- PR_GetError(), slapd_pr_strerror(PR_GetError()),
- errno, slapd_system_strerror(errno));
- goto done;
- }
-
- if (msgidp) { /* let caller process result */
- *msgidp = mymsgid;
- } else { /* process results */
- rc = ldap_result(ld, mymsgid, LDAP_MSG_ALL, timeout, &result);
- if (-1 == rc) { /* error */
- rc = ldap_get_lderrno(ld, NULL, NULL);
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error reading bind response for id "
- "[%s] mech [%s]: error %d (%s)\n",
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE",
- rc, ldap_err2string(rc));
- goto done;
- } else if (rc == 0) { /* timeout */
- rc = LDAP_TIMEOUT;
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: timeout after [%ld.%ld] seconds reading "
- "bind response for [%s] mech [%s]\n",
- timeout ? timeout->tv_sec : 0,
- timeout ? timeout->tv_usec : 0,
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE");
- goto done;
- }
- /* if we got here, we were able to read success result */
- /* Get the controls sent by the server if requested */
- if (returnedctrls) {
- if ((rc = ldap_parse_result(ld, result, &rc, NULL, NULL,
- NULL, returnedctrls,
- 0)) != LDAP_SUCCESS) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: could not bind id "
- "[%s] mech [%s]: error %d (%s)\n",
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE",
- rc, ldap_err2string(rc));
- goto done;
- }
- }
-
- /* parse the bind result and get the ldap error code */
- if ((rc = ldap_parse_sasl_bind_result(ld, result, &servercredp,
- 0)) ||
- (rc = ldap_result2error(ld, result, 0))) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: could not read bind results for id "
- "[%s] mech [%s]: error %d (%s)\n",
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE",
- rc, ldap_err2string(rc));
- goto done;
- }
- }
- } else {
- /* a SASL mech - set the sasl ssf to 0 if using TLS/SSL */
- if (secure) {
- sasl_ssf_t max_ssf = 0;
- ldap_set_option(ld, LDAP_OPT_X_SASL_SSF_MAX, &max_ssf);
- }
- rc = slapd_ldap_sasl_interactive_bind(ld, bindid, creds, mech,
- serverctrls, returnedctrls,
- msgidp);
- if (LDAP_SUCCESS != rc) {
- slapi_log_error(SLAPI_LOG_FATAL, "slapi_ldap_bind",
- "Error: could not perform interactive bind for id "
- "[%s] mech [%s]: error %d (%s)\n",
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE",
- rc, ldap_err2string(rc));
- }
- }
-
-done:
- slapi_ch_bvfree(&servercredp);
- ldap_msgfree(result);
-
- return rc;
-}
-
-/* the following implements the client side of sasl bind, for LDAP server
- -> LDAP server SASL */
-
-typedef struct {
- char *mech;
- char *authid;
- char *username;
- char *passwd;
- char *realm;
-} ldapSaslInteractVals;
-
-#ifdef HAVE_KRB5
-static void set_krb5_creds(
- const char *authid,
- const char *username,
- const char *passwd,
- const char *realm,
- ldapSaslInteractVals *vals
-);
-#endif
-
-static void *
-ldap_sasl_set_interact_vals(LDAP *ld, const char *mech, const char *authid,
- const char *username, const char *passwd,
- const char *realm)
-{
- ldapSaslInteractVals *vals = NULL;
- char *idprefix = "";
-
- vals = (ldapSaslInteractVals *)
- slapi_ch_calloc(1, sizeof(ldapSaslInteractVals));
-
- if (!vals) {
- return NULL;
- }
-
- if (mech) {
- vals->mech = slapi_ch_strdup(mech);
- } else {
- ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &vals->mech);
- }
-
- if (vals->mech && !strcasecmp(vals->mech, "DIGEST-MD5")) {
- idprefix = "dn:"; /* prefix name and id with this string */
- }
-
- if (authid) { /* use explicit passed in value */
- vals->authid = slapi_ch_smprintf("%s%s", idprefix, authid);
- } else { /* use option value if any */
- ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &vals->authid);
- if (!vals->authid) {
-/* get server user id? */
- vals->authid = slapi_ch_strdup("");
- }
- }
-
- if (username) { /* use explicit passed in value */
- vals->username = slapi_ch_smprintf("%s%s", idprefix, username);
- } else { /* use option value if any */
- ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &vals->username);
- if (!vals->username) { /* use default sasl value */
- vals->username = slapi_ch_strdup("");
- }
- }
-
- if (passwd) {
- vals->passwd = slapi_ch_strdup(passwd);
- } else {
- vals->passwd = slapi_ch_strdup("");
- }
-
- if (realm) {
- vals->realm = slapi_ch_strdup(realm);
- } else {
- ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &vals->realm);
- if (!vals->realm) { /* use default sasl value */
- vals->realm = slapi_ch_strdup("");
- }
- }
-
-#ifdef HAVE_KRB5
- if (mech && !strcmp(mech, "GSSAPI")) {
- set_krb5_creds(authid, username, passwd, realm, vals);
- }
-#endif /* HAVE_KRB5 */
-
- return vals;
-}
-
-static void
-ldap_sasl_free_interact_vals(void *defaults)
-{
- ldapSaslInteractVals *vals = defaults;
-
- if (vals) {
- slapi_ch_free_string(&vals->mech);
- slapi_ch_free_string(&vals->authid);
- slapi_ch_free_string(&vals->username);
- slapi_ch_free_string(&vals->passwd);
- slapi_ch_free_string(&vals->realm);
- slapi_ch_free(&defaults);
- }
-}
-
-static int
-ldap_sasl_get_val(ldapSaslInteractVals *vals, sasl_interact_t *interact, unsigned flags)
-{
- const char *defvalue = interact->defresult;
- int authtracelevel = SLAPI_LOG_SHELL; /* special auth tracing */
-
- if (vals != NULL) {
- switch(interact->id) {
- case SASL_CB_AUTHNAME:
- defvalue = vals->authid;
- slapi_log_error(authtracelevel, "ldap_sasl_get_val",
- "Using value [%s] for SASL_CB_AUTHNAME\n",
- defvalue ? defvalue : "(null)");
- break;
- case SASL_CB_USER:
- defvalue = vals->username;
- slapi_log_error(authtracelevel, "ldap_sasl_get_val",
- "Using value [%s] for SASL_CB_USER\n",
- defvalue ? defvalue : "(null)");
- break;
- case SASL_CB_PASS:
- defvalue = vals->passwd;
- slapi_log_error(authtracelevel, "ldap_sasl_get_val",
- "Using value [%s] for SASL_CB_PASS\n",
- defvalue ? defvalue : "(null)");
- break;
- case SASL_CB_GETREALM:
- defvalue = vals->realm;
- slapi_log_error(authtracelevel, "ldap_sasl_get_val",
- "Using value [%s] for SASL_CB_GETREALM\n",
- defvalue ? defvalue : "(null)");
- break;
- }
- }
-
- if (defvalue != NULL) {
- interact->result = defvalue;
- if ((char *)interact->result == NULL)
- return (LDAP_NO_MEMORY);
- interact->len = strlen((char *)(interact->result));
- }
- return (LDAP_SUCCESS);
-}
-
-static int
-ldap_sasl_interact_cb(LDAP *ld, unsigned flags, void *defaults, void *prompts)
-{
- sasl_interact_t *interact = NULL;
- ldapSaslInteractVals *sasldefaults = defaults;
- int rc;
-
- if (prompts == NULL) {
- return (LDAP_PARAM_ERROR);
- }
-
- for (interact = prompts; interact->id != SASL_CB_LIST_END; interact++) {
- /* Obtain the default value */
- if ((rc = ldap_sasl_get_val(sasldefaults, interact, flags)) != LDAP_SUCCESS) {
- return (rc);
- }
- }
-
- return (LDAP_SUCCESS);
-}
-
-/* figure out from the context and this error if we should
- attempt to retry the bind */
-static int
-can_retry_bind(LDAP *ld, const char *mech, const char *bindid,
- const char *creds, int rc, const char *errmsg)
-{
- int localrc = 0;
- if (errmsg && strstr(errmsg, "Ticket expired")) {
- localrc = 1;
- }
-
- return localrc;
-}
-
-int
-slapd_ldap_sasl_interactive_bind(
- LDAP *ld, /* ldap connection */
- const char *bindid, /* usually a bind DN for simple bind */
- const char *creds, /* usually a password for simple bind */
- const char *mech, /* name of mechanism */
- LDAPControl **serverctrls, /* additional controls to send */
- LDAPControl ***returnedctrls, /* returned controls */
- int *msgidp /* pass in non-NULL for async handling */
-)
-{
- int rc = LDAP_SUCCESS;
- int tries = 0;
-
- while (tries < 2) {
- void *defaults = ldap_sasl_set_interact_vals(ld, mech, bindid, bindid,
- creds, NULL);
- /* have to first set the defaults used by the callback function */
- /* call the bind function */
- rc = ldap_sasl_interactive_bind_ext_s(ld, bindid, mech, serverctrls,
- NULL, LDAP_SASL_QUIET,
- ldap_sasl_interact_cb, defaults,
- returnedctrls);
- ldap_sasl_free_interact_vals(defaults);
- if (LDAP_SUCCESS != rc) {
- char *errmsg = NULL;
- rc = ldap_get_lderrno(ld, NULL, &errmsg);
- slapi_log_error(SLAPI_LOG_FATAL, "slapd_ldap_sasl_interactive_bind",
- "Error: could not perform interactive bind for id "
- "[%s] mech [%s]: error %d (%s) (%s)\n",
- bindid ? bindid : "(anon)",
- mech ? mech : "SIMPLE",
- rc, ldap_err2string(rc), errmsg);
- if (can_retry_bind(ld, mech, bindid, creds, rc, errmsg)) {
- ; /* pass through to retry one time */
- } else {
- break; /* done - fail - cannot retry */
- }
- } else {
- break; /* done - success */
- }
- tries++;
- }
-
- return rc;
-}
-
-#ifdef HAVE_KRB5
-#include <krb5.h>
-
-/* for some reason this is not in the public API?
- but it is documented e.g. man kinit */
-#ifndef KRB5_ENV_CCNAME
-#define KRB5_ENV_CCNAME "KRB5CCNAME"
-#endif
-
-static void
-show_one_credential(int authtracelevel,
- krb5_context ctx, krb5_creds *cred)
-{
- char *logname = "show_one_credential";
- krb5_error_code rc;
- char *name = NULL, *sname = NULL;
- char startts[BUFSIZ], endts[BUFSIZ], renewts[BUFSIZ];
-
- if ((rc = krb5_unparse_name(ctx, cred->client, &name))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get client name from credential: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
- if ((rc = krb5_unparse_name(ctx, cred->server, &sname))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get server name from credential: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
- if (!cred->times.starttime) {
- cred->times.starttime = cred->times.authtime;
- }
- krb5_timestamp_to_sfstring((krb5_timestamp)cred->times.starttime,
- startts, sizeof(startts), NULL);
- krb5_timestamp_to_sfstring((krb5_timestamp)cred->times.endtime,
- endts, sizeof(endts), NULL);
- krb5_timestamp_to_sfstring((krb5_timestamp)cred->times.renew_till,
- renewts, sizeof(renewts), NULL);
-
- slapi_log_error(authtracelevel, logname,
- "\tKerberos credential: client [%s] server [%s] "
- "start time [%s] end time [%s] renew time [%s] "
- "flags [0x%x]\n", name, sname, startts, endts,
- renewts, (uint32_t)cred->ticket_flags);
-
-cleanup:
- krb5_free_unparsed_name(ctx, name);
- krb5_free_unparsed_name(ctx, sname);
-
- return;
-}
-
-/*
- * Call this after storing the credentials in the cache
- */
-static void
-show_cached_credentials(int authtracelevel,
- krb5_context ctx, krb5_ccache cc,
- krb5_principal princ)
-{
- char *logname = "show_cached_credentials";
- krb5_error_code rc = 0;
- krb5_creds creds;
- krb5_cc_cursor cur;
- char *princ_name = NULL;
-
- if ((rc = krb5_unparse_name(ctx, princ, &princ_name))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get principal name from principal: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
-
- slapi_log_error(authtracelevel, logname,
- "Ticket cache: %s:%s\nDefault principal: %s\n\n",
- krb5_cc_get_type(ctx, cc),
- krb5_cc_get_name(ctx, cc), princ_name);
-
- if ((rc = krb5_cc_start_seq_get(ctx, cc, &cur))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get cursor to iterate cached credentials: "
- "%d (%s)\n", rc, error_message(rc));
- goto cleanup;
- }
-
- while (!(rc = krb5_cc_next_cred(ctx, cc, &cur, &creds))) {
- show_one_credential(authtracelevel, ctx, &creds);
- krb5_free_cred_contents(ctx, &creds);
- }
- if (rc == KRB5_CC_END) {
- if ((rc = krb5_cc_end_seq_get(ctx, cc, &cur))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not close cached credentials cursor: "
- "%d (%s)\n", rc, error_message(rc));
- goto cleanup;
- }
- }
-
-cleanup:
- krb5_free_unparsed_name(ctx, princ_name);
-
- return;
-}
-
-static int
-looks_like_a_dn(const char *username)
-{
- return (username && strchr(username, '='));
-}
-
-static int
-credentials_are_valid(
- krb5_context ctx,
- krb5_ccache cc,
- krb5_principal princ,
- const char *princ_name,
- int *rc
-)
-{
- char *logname = "credentials_are_valid";
- int myrc = 0;
- krb5_creds mcreds; /* match these values */
- krb5_creds creds; /* returned creds */
- char *tgs_princ_name = NULL;
- krb5_timestamp currenttime;
- int authtracelevel = SLAPI_LOG_SHELL; /* special auth tracing */
- int realm_len;
- char *realm_str;
- int time_buffer = 30; /* seconds - go ahead and renew if creds are
- about to expire */
-
- memset(&mcreds, 0, sizeof(mcreds));
- memset(&creds, 0, sizeof(creds));
- *rc = 0;
- if (!cc) {
- /* ok - no error */
- goto cleanup;
- }
-
- /* have to construct the tgs server principal in
- order to set mcreds.server required in order
- to use krb5_cc_retrieve_creds() */
- /* get default realm first */
- realm_len = krb5_princ_realm(ctx, princ)->length;
- realm_str = krb5_princ_realm(ctx, princ)->data;
- tgs_princ_name = slapi_ch_smprintf("%s/%*s@%*s", KRB5_TGS_NAME,
- realm_len, realm_str,
- realm_len, realm_str);
-
- if ((*rc = krb5_parse_name(ctx, tgs_princ_name, &mcreds.server))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could parse principal [%s]: %d (%s)\n",
- tgs_princ_name, *rc, error_message(*rc));
- goto cleanup;
- }
-
- mcreds.client = princ;
- if ((*rc = krb5_cc_retrieve_cred(ctx, cc, 0, &mcreds, &creds))) {
- if (*rc == KRB5_CC_NOTFOUND) {
- /* ok - no creds for this princ in the cache */
- *rc = 0;
- }
- goto cleanup;
- }
-
- /* have the creds - now look at the timestamp */
- if ((*rc = krb5_timeofday(ctx, &currenttime))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get current time: %d (%s)\n",
- *rc, error_message(*rc));
- goto cleanup;
- }
-
- if (currenttime > (creds.times.endtime + time_buffer)) {
- slapi_log_error(authtracelevel, logname,
- "Credentials for [%s] have expired or will soon "
- "expire - now [%d] endtime [%d]\n", princ_name,
- currenttime, creds.times.endtime);
- goto cleanup;
- }
-
- myrc = 1; /* credentials are valid */
-cleanup:
- krb5_free_cred_contents(ctx, &creds);
- slapi_ch_free_string(&tgs_princ_name);
- if (mcreds.server) {
- krb5_free_principal(ctx, mcreds.server);
- }
-
- return myrc;
-}
-
-/*
- * This implementation assumes that we want to use the
- * keytab from the default keytab env. var KRB5_KTNAME
- * as. This code is very similar to kinit -k -t. We
- * get a krb context, get the default keytab, get
- * the credentials from the keytab, authenticate with
- * those credentials, create a ccache, store the
- * credentials in the ccache, and set the ccache
- * env var to point to those credentials.
- */
-static void
-set_krb5_creds(
- const char *authid,
- const char *username,
- const char *passwd,
- const char *realm,
- ldapSaslInteractVals *vals
-)
-{
- char *logname = "set_krb5_creds";
- const char *cc_type = "MEMORY"; /* keep cred cache in memory */
- krb5_context ctx = NULL;
- krb5_ccache cc = NULL;
- krb5_principal princ = NULL;
- char *princ_name = NULL;
- krb5_error_code rc = 0;
- krb5_creds creds;
- krb5_keytab kt = NULL;
- char *cc_name = NULL;
- char ktname[MAX_KEYTAB_NAME_LEN];
- static char cc_env_name[1024+32]; /* size from ccdefname.c */
- int new_ccache = 0;
- int authtracelevel = SLAPI_LOG_SHELL; /* special auth tracing
- not sure what shell was
- used for, does not
- appear to be used
- currently */
-
- /* probably have to put a mutex around this whole thing, to avoid
- problems with reentrancy, since we are setting a "global"
- variable via an environment variable */
-
- /* wipe this out so we can safely free it later if we
- short circuit */
- memset(&creds, 0, sizeof(creds));
-
- /* initialize the kerberos context */
- if ((rc = krb5_init_context(&ctx))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not init Kerberos context: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
-
- /* see if there is already a ccache, and see if there are
- creds in the ccache */
- /* grab the default ccache - note: this does not open the cache */
- if ((rc = krb5_cc_default(ctx, &cc))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get default Kerberos ccache: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
-
- /* use this cache - construct the full cache name */
- cc_name = slapi_ch_smprintf("%s:%s", krb5_cc_get_type(ctx, cc),
- krb5_cc_get_name(ctx, cc));
-
- /* grab the principal from the ccache - will fail if there
- is no ccache */
- if ((rc = krb5_cc_get_principal(ctx, cc, &princ))) {
- if (KRB5_FCC_NOFILE == rc) { /* no cache - ok */
- slapi_log_error(authtracelevel, logname,
- "The default credentials cache [%s] not found: "
- "will create a new one.\n", cc_name);
- /* close the cache - we will create a new one below */
- krb5_cc_close(ctx, cc);
- cc = NULL;
- slapi_ch_free_string(&cc_name);
- /* fall through to the keytab auth code below */
- } else { /* fatal */
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not open default Kerberos ccache [%s]: "
- "%d (%s)\n", cc_name, rc, error_message(rc));
- goto cleanup;
- }
- } else { /* have a valid ccache && found principal */
- if ((rc = krb5_unparse_name(ctx, princ, &princ_name))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Unable to get name of principal from ccache [%s]: "
- "%d (%s)\n", cc_name, rc, error_message(rc));
- goto cleanup;
- }
- slapi_log_error(authtracelevel, logname,
- "Using principal [%s] from ccache [%s]\n",
- princ_name, cc_name);
- }
-
- /* if this is not our type of ccache, there is nothing more we can
- do - just punt and let sasl/gssapi take it's course - this
- usually means there has been an external kinit e.g. in the
- start up script, and it is the responsibility of the script to
- renew those credentials or face lots of sasl/gssapi failures
- This means, however, that the caller MUST MAKE SURE THERE IS NO
- DEFAULT CCACHE FILE or the server will attempt to use it (and
- likely fail) - THERE MUST BE NO DEFAULT CCACHE FILE IF YOU WANT
- THE SERVER TO AUTHENTICATE WITH THE KEYTAB
- NOTE: cc types are case sensitive and always upper case */
- if (cc && strcmp(cc_type, krb5_cc_get_type(ctx, cc))) {
- static int errmsgcounter = 0;
- int loglevel = SLAPI_LOG_FATAL;
- if (errmsgcounter) {
- loglevel = authtracelevel;
- }
- /* make sure we log this message once, in case the user has
- done something unintended, we want to make sure they know
- about it. However, if the user knows what he/she is doing,
- by using an external ccache file, they probably don't want
- to be notified with an error every time. */
- slapi_log_error(loglevel, logname,
- "The server will use the external SASL/GSSAPI "
- "credentials cache [%s:%s]. If you want the "
- "server to automatically authenticate with its "
- "keytab, you must remove this cache. If you "
- "did not intend to use this cache, you will likely "
- "see many SASL/GSSAPI authentication failures.\n",
- krb5_cc_get_type(ctx, cc), krb5_cc_get_name(ctx, cc));
- errmsgcounter++;
- goto cleanup;
- }
-
- /* need to figure out which principal to use
- 1) use the one from the ccache
- 2) use username
- 3) construct one in the form ldap/fqdn@REALM
- */
- if (!princ && username && !looks_like_a_dn(username) &&
- (rc = krb5_parse_name(ctx, username, &princ))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Error: could not convert [%s] into a kerberos "
- "principal: %d (%s)\n", username,
- rc, error_message(rc));
- goto cleanup;
- }
-
- /* if still no principal, construct one */
- if (!princ &&
- (rc = krb5_sname_to_principal(ctx, NULL, "ldap",
- KRB5_NT_SRV_HST, &princ))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Error: could not construct ldap service "
- "principal: %d (%s)\n", rc, error_message(rc));
- goto cleanup;
- }
-
- if ((rc = krb5_unparse_name(ctx, princ, &princ_name))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Unable to get name of principal: "
- "%d (%s)\n", rc, error_message(rc));
- goto cleanup;
- }
-
- slapi_log_error(authtracelevel, logname,
- "Using principal named [%s]\n", princ_name);
-
- /* grab the credentials from the ccache, if any -
- if the credentials are still valid, we do not have
- to authenticate again */
- if (credentials_are_valid(ctx, cc, princ, princ_name, &rc)) {
- slapi_log_error(authtracelevel, logname,
- "Credentials for principal [%s] are still "
- "valid - no auth is necessary.\n",
- princ_name);
- goto cleanup;
- } else if (rc) { /* some error other than "there are no credentials" */
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Unable to verify cached credentials for "
- "principal [%s]: %d (%s)\n", princ_name,
- rc, error_message(rc));
- goto cleanup;
- }
-
- /* find our default keytab */
- if ((rc = krb5_kt_default(ctx, &kt))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Unable to get default keytab: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
-
- /* get name of keytab for debugging purposes */
- if ((rc = krb5_kt_get_name(ctx, kt, ktname, sizeof(ktname)))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Unable to get name of default keytab: %d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
-
- slapi_log_error(authtracelevel, logname,
- "Using keytab named [%s]\n", ktname);
-
- /* now do the actual kerberos authentication using
- the keytab, and get the creds */
- rc = krb5_get_init_creds_keytab(ctx, &creds, princ, kt,
- 0, NULL, NULL);
- if (rc) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not get initial credentials for principal [%s] "
- "in keytab [%s]: %d (%s)\n",
- princ_name, ktname, rc, error_message(rc));
- goto cleanup;
- }
-
- /* completely done with the keytab now, close it */
- krb5_kt_close(ctx, kt);
- kt = NULL; /* no double free */
-
- /* we now have the creds and the principal to which the
- creds belong - use or allocate a new memory based
- cache to hold the creds */
- if (!cc_name) {
-#if HAVE_KRB5_CC_NEW_UNIQUE
- /* krb5_cc_new_unique is a new convenience function which
- generates a new unique name and returns a memory
- cache with that name */
- if ((rc = krb5_cc_new_unique(ctx, cc_type, NULL, &cc))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not create new unique memory ccache: "
- "%d (%s)\n",
- rc, error_message(rc));
- goto cleanup;
- }
- cc_name = slapi_ch_smprintf("%s:%s", cc_type,
- krb5_cc_get_name(ctx, cc));
-#else
- /* store the cache in memory - krb5_init_context uses malloc
- to create the ctx, so the address should be unique enough
- for our purposes */
- if (!(cc_name = slapi_ch_smprintf("%s:%p", cc_type, ctx))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could create Kerberos memory ccache: "
- "out of memory\n");
- rc = 1;
- goto cleanup;
- }
-#endif
- slapi_log_error(authtracelevel, logname,
- "Generated new memory ccache [%s]\n", cc_name);
- new_ccache = 1; /* need to set this in env. */
- } else {
- slapi_log_error(authtracelevel, logname,
- "Using existing ccache [%s]\n", cc_name);
- }
-
- /* krb5_cc_resolve is basically like an init -
- this creates the cache structure, and creates a slot
- for the cache in the static linked list in memory, if
- there is not already a slot -
- see cc_memory.c for details
- cc could already have been created by new_unique above
- */
- if (!cc && (rc = krb5_cc_resolve(ctx, cc_name, &cc))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not create ccache [%s]: %d (%s)\n",
- cc_name, rc, error_message(rc));
- goto cleanup;
- }
-
- /* wipe out previous contents of cache for this principal, if any */
- if ((rc = krb5_cc_initialize(ctx, cc, princ))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not initialize ccache [%s] for the new "
- "credentials for principal [%s]: %d (%s)\n",
- cc_name, princ_name, rc, error_message(rc));
- goto cleanup;
- }
-
- /* store the credentials in the cache */
- if ((rc = krb5_cc_store_cred(ctx, cc, &creds))) {
- slapi_log_error(SLAPI_LOG_FATAL, logname,
- "Could not store the credentials in the "
- "ccache [%s] for principal [%s]: %d (%s)\n",
- cc_name, princ_name, rc, error_message(rc));
- goto cleanup;
- }
-
- /* now, do a "klist" to show the credential information, and log it */
- show_cached_credentials(authtracelevel, ctx, cc, princ);
-
- /* set the CC env var to the value of the cc cache name */
- /* since we can't pass krb5 context up and out of here
- and down through the ldap sasl layer, we set this
- env var so that calls to krb5_cc_default_name will
- use this */
- if (new_ccache) {
- PR_snprintf(cc_env_name, sizeof(cc_env_name),
- "%s=%s", KRB5_ENV_CCNAME, cc_name);
- PR_SetEnv(cc_env_name);
- slapi_log_error(authtracelevel, logname,
- "Set new env for ccache: [%s]\n",
- cc_env_name);
- }
-
-cleanup:
- /* use NULL as username and authid */
- slapi_ch_free_string(&vals->username);
- slapi_ch_free_string(&vals->authid);
-
- krb5_free_unparsed_name(ctx, princ_name);
- if (kt) { /* NULL not allowed */
- krb5_kt_close(ctx, kt);
- }
- if (creds.client == princ) {
- creds.client = NULL;
- }
- krb5_free_cred_contents(ctx, &creds);
- slapi_ch_free_string(&cc_name);
- krb5_free_principal(ctx, princ);
- if (cc) {
- krb5_cc_close(ctx, cc);
- }
- if (ctx) { /* cannot pass NULL to free context */
- krb5_free_context(ctx);
- }
- return;
-}
-
-#endif /* HAVE_KRB5 */
diff --git a/ldap/servers/snmp/main.c b/ldap/servers/snmp/main.c
index 89732faf..5b2ad68a 100644
--- a/ldap/servers/snmp/main.c
+++ b/ldap/servers/snmp/main.c
@@ -47,6 +47,7 @@
#include <signal.h>
#include <sys/stat.h>
#include "ldap-agent.h"
+#include "ldap.h"
#include "ldif.h"
static char *agentx_master = NULL;
@@ -245,7 +246,12 @@ load_config(char *conf_path)
{
server_instance *serv_p = NULL;
FILE *conf_file = NULL;
+#if defined(USE_OPENLDAP)
+ LDIFFP *dse_fp = NULL;
+ int buflen;
+#else
FILE *dse_fp = NULL;
+#endif
char line[MAXLINE];
char *p = NULL;
int error = 0;
@@ -371,7 +377,12 @@ load_config(char *conf_path)
}
/* Open dse.ldif */
- if ((dse_fp = fopen(serv_p->dse_ldif, "r")) == NULL) {
+#if defined(USE_OPENLDAP)
+ dse_fp = ldif_open(serv_p->dse_ldif, "r");
+#else
+ dse_fp = fopen(serv_p->dse_ldif, "r");
+#endif
+ if (dse_fp == NULL) {
printf("ldap-agent: Error opening server config file: %s\n",
serv_p->dse_ldif);
error = 1;
@@ -386,12 +397,20 @@ load_config(char *conf_path)
* the pointer that is passed to it, so we need to save a
* pointer to the beginning of the entry so we can free it
* later. */
- while ((entry = ldif_get_entry(dse_fp, &lineno)) != NULL) {
+#if defined(USE_OPENLDAP)
+ while (ldif_read_record(dse_fp, &lineno, &entry, &buflen))
+#else
+ while ((entry = ldif_get_entry(dse_fp, &lineno)) != NULL)
+#endif
+ {
char *entryp = entry;
char *attr = NULL;
char *val = NULL;
+#if defined(USE_OPENLDAP)
+ ber_len_t vlen;
+#else
int vlen;
-
+#endif
/* Check if this is the cn=config entry */
ldif_parse_line(ldif_getline(&entryp), &attr, &val, &vlen);
if ((strcmp(attr, "dn") == 0) &&
@@ -470,8 +489,13 @@ load_config(char *conf_path)
close_and_exit:
if (conf_file)
fclose(conf_file);
- if (dse_fp)
+ if (dse_fp) {
+#if defined(USE_OPENLDAP)
+ ldif_close(dse_fp);
+#else
fclose(dse_fp);
+#endif
+ }
if (error)
exit(error);
}