ldap/servers/slapd/mozldap.h | 45 +++++++++++++++++++++++++++++++++++++++++++
ldap/servers/slapd/sasl_io.c | 39 ++++++++++++++++++++++++++++++++++---
2 files changed, 81 insertions(+), 3 deletions(-)
New commits:
commit 62c89ea8e34fa19755a5d26c4b8dee81c47670ea
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Oct 2 17:26:11 2013 -0400
Ticket 47531 - Mozldap - need to rewrite sasl_io_recv
Bug Description: Mozldap does not have some "ber" functions
(ber_skip_element) that
are in openldap. This causes the build to fail.
Fix Description: To parse the ber we need a local copy of the ber structure(which I
called MozElement), so that the ber_ptr can be manipulated. I had
to
use a new header file(mozldap.h), because the mozldap BerElement
typedef's
caused build failures.
There is also a mozldap version check, and if the verison is newer
than
what was used for mozldap.h, the build will fail. The current
internal
version is 604, even though the rpm says 605.
https://fedorahosted.org/389/ticket/47531
Reviewed by: richm(Thanks!)
diff --git a/ldap/servers/slapd/mozldap.h b/ldap/servers/slapd/mozldap.h
new file mode 100644
index 0000000..cd3cb2e
--- /dev/null
+++ b/ldap/servers/slapd/mozldap.h
@@ -0,0 +1,45 @@
+/*
+ * mozldap does not have all the openldap "ber" functions, like
ber_skip_element.
+ * So we need to directly parse the ber element, and see inside the ber struct.
+ * From lber-int.h
+ */
+typedef struct seqorset {
+ ber_len_t sos_clen;
+ ber_tag_t sos_tag;
+ char *sos_first;
+ char *sos_ptr;
+ struct seqorset *sos_next;
+} Seqorset;
+
+#define SOS_STACK_SIZE 8 /* depth of the pre-allocated sos structure stack */
+#define MAX_TAG_SIZE (1 + sizeof(ber_int_t)) /* One byte for the length of the tag */
+#define MAX_LEN_SIZE (1 + sizeof(ber_int_t)) /* One byte for the length of the length */
+#define MAX_VALUE_PREFIX_SIZE (2 + sizeof(ber_int_t)) /* 1 byte for the tag and 1 for the
len (msgid) */
+#define BER_ARRAY_QUANTITY 7 /* 0:Tag 1:Length 2:Value-prefix 3:Value
4:Value-suffix */
+
+struct berelement {
+ ldap_x_iovec ber_struct[BER_ARRAY_QUANTITY]; /* See above */
+ char ber_tag_contents[MAX_TAG_SIZE];
+ char ber_len_contents[MAX_LEN_SIZE];
+ char ber_pre_contents[MAX_VALUE_PREFIX_SIZE];
+ char ber_suf_contents[MAX_LEN_SIZE+1];
+ char *ber_buf; /* update the value value when writing in case realloc is
called */
+ char *ber_ptr;
+ char *ber_end;
+ struct seqorset *ber_sos;
+ ber_len_t ber_tag_len_read;
+ ber_tag_t ber_tag; /* Remove me someday */
+ ber_len_t ber_len; /* Remove me someday */
+ int ber_usertag;
+ char ber_options;
+ char *ber_rwptr;
+ BERTranslateProc ber_encode_translate_proc;
+ BERTranslateProc ber_decode_translate_proc;
+ int ber_flags;
+#define LBER_FLAG_NO_FREE_BUFFER 1 /* don't free ber_buf */
+ unsigned int ber_buf_reallocs; /* realloc counter */
+ int ber_sos_stack_posn;
+ Seqorset ber_sos_stack[SOS_STACK_SIZE];
+};
+typedef struct berelement MozElement;
+
diff --git a/ldap/servers/slapd/sasl_io.c b/ldap/servers/slapd/sasl_io.c
index b39f22d..3fe9057 100644
--- a/ldap/servers/slapd/sasl_io.c
+++ b/ldap/servers/slapd/sasl_io.c
@@ -45,6 +45,14 @@
#include "fe.h"
#include <sasl.h>
#include <arpa/inet.h>
+#ifndef USE_OPENLDAP
+#include "mozldap.h"
+#if LDAP_VENDOR_VERSION > 604
+/* garbage to cause build to fail */
+MOZLDAP is newer than expected, if the ber structure has not changed
+(see ldap/server/slapd/mozldap.h), please bump the version number(604 -> new version)
+#endif
+#endif
/*
* I/O Shim Layer for SASL Encryption
@@ -261,11 +269,16 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime
timeout, PRInt
* Check if an LDAP operation was sent unencrypted
*/
if(!sp->send_encrypted && *sp->encrypted_buffer == LDAP_TAG_MESSAGE){
- struct berval bv, tmp_bv;
+ struct berval bv;
+#ifdef USE_OPENLDAP
BerElement *ber = NULL;
+ struct berval tmp_bv;
+#else
+ MozElement *ber = NULL;
+#endif
ber_len_t maxbersize = config_get_maxbersize();
ber_len_t ber_len = 0;
- ber_tag_t tag;
+ ber_tag_t tag = 0;
slapi_log_error( SLAPI_LOG_CONNS, "sasl_io_start_packet",
"conn=%" NSPRIu64 " fd=%d "
"Sent an LDAP message that was not encrypted.\n", (long long
unsigned int)c->c_connid,
@@ -340,7 +353,12 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime
timeout, PRInt
*/
bv.bv_val = sp->encrypted_buffer;
bv.bv_len = sp->encrypted_buffer_offset;
+
+#ifdef USE_OPENLDAP
if ( (ber = ber_init(&bv)) == NULL){
+#else
+ if ( (ber = (MozElement *)ber_init(&bv)) == NULL){
+#endif
goto done;
}
@@ -348,16 +366,27 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime
timeout, PRInt
* Start parsing the berElement. First skip this tag, and move on to the
* tag msgid
*/
+#ifdef USE_OPENLDAP
ber_skip_tag(ber, &ber_len);
if( ber_peek_tag( ber, &ber_len ) == LDAP_TAG_MSGID) {
+#else
+ ber_skip_tag((BerElement*)ber, &ber_len);
+ if( ber_peek_tag( (BerElement*)ber, &ber_len ) == LDAP_TAG_MSGID) {
+#endif
/*
* Skip the entire msgid element, so we can get to the LDAP op tag
*/
+#ifdef USE_OPENLDAP
if(ber_skip_element(ber, &tmp_bv) == LDAP_TAG_MSGID) {
/*
* We only allow unbind operations to be processed for unencrypted
operations
*/
if (( tag = ber_peek_tag( ber, &ber_len )) == LDAP_REQ_UNBIND ) {
+#else
+ {
+ tag = *ber->ber_ptr++;
+ if (*ber->ber_ptr == LDAP_REQ_UNBIND){
+#endif
slapi_log_error( SLAPI_LOG_CONNS, "sasl_io_start_packet",
"conn=%" NSPRIu64 " fd=%d "
"Received unencrypted UNBIND operation.\n", (long
long unsigned int)c->c_connid,
c->c_sd);
@@ -368,7 +397,11 @@ sasl_io_start_packet(PRFileDesc *fd, PRIntn flags, PRIntervalTime
timeout, PRInt
}
slapi_log_error( SLAPI_LOG_CONNS, "sasl_io_start_packet",
"conn=%" NSPRIu64 " fd=%d "
"Error: received an LDAP message (tag 0x%lx) that was not
encrypted.\n",
- (long long unsigned int)c->c_connid, c->c_sd, tag);
+#ifdef USE_OPENLDAP
+ (long long unsigned int)c->c_connid, c->c_sd, (long
unsigned int)tag);
+#else
+ (long long unsigned int)c->c_connid, c->c_sd, (long
unsigned int)*ber->ber_ptr);
+#endif
}
}