Tuesday, June 3, 2014

[389-commits] ldap/servers

ldap/servers/plugins/sync/sync.h | 1
ldap/servers/plugins/sync/sync_persist.c | 8 ++----
ldap/servers/plugins/sync/sync_util.c | 16 ++++++++++---
ldap/servers/slapd/operation.c | 38 +++++++++++++++++++++++++++++++
ldap/servers/slapd/pblock.c | 12 +++++++++
ldap/servers/slapd/slapi-plugin.h | 7 +++++
6 files changed, 74 insertions(+), 8 deletions(-)

New commits:
commit a81a3ead42f83e8c928fde07db9fd2fff5ce4c96
Author: Ludwig Krispenz <lkrispen@redhat.com>
Date: Mon Jun 2 14:10:54 2014 +0200

Ticket 47803 - syncrepl crash if attribute list is non-empty

Bug Description: if the list of requested attributes in a persistent
sync repl request was set, the server could
crash after a modify operation which should
send an entry

Fix Description: the reason for the crash was that the list of requested
attributes was freed when the original search
operation was completed. In the persit phase this
list was still accessed.
To fix it, a copy of the orignal op had to be used
and the list of requested attr duplicated and set
in the copy of the op.
unfortunately a reference to the original op is
still needed as the disconnet code sets the abandonned
flag to the original op
To be able to duplicate an operation, some methods to get
and set operation attributes had to be provided

https://fedorahosted.org/389/ticket/47803

Reviewed by: RichM. ThanksRichM. Thanks

diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h
index 9168039..9c2d8be 100644
--- a/ldap/servers/plugins/sync/sync.h
+++ b/ldap/servers/plugins/sync/sync.h
@@ -158,6 +158,7 @@ typedef struct sync_queue_node {
*/
typedef struct sync_request {
Slapi_PBlock *req_pblock;
+ Slapi_Operation *req_orig_op;
PRLock *req_lock;
PRThread *req_tid;
char *req_orig_base;
diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c
index 4fb4574..8d46102 100644
--- a/ldap/servers/plugins/sync/sync_persist.c
+++ b/ldap/servers/plugins/sync/sync_persist.c
@@ -292,6 +292,7 @@ sync_persist_add (Slapi_PBlock *pb)
if ( SYNC_IS_INITIALIZED() && NULL != pb ) {
/* Create the new node */
req = sync_request_alloc();
+ slapi_pblock_get(pb, SLAPI_OPERATION, &req->req_orig_op); /* neede to access original op */
req->req_pblock = sync_pblock_copy(pb);
slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &base);
req->req_orig_base = slapi_ch_strdup(base);
@@ -566,7 +567,7 @@ sync_send_results( void *arg )
SyncQueueNode *qnode, *qnodenext;
int conn_acq_flag = 0;
Slapi_Connection *conn = NULL;
- Slapi_Operation *op = NULL;
+ Slapi_Operation *op = req->req_orig_op;
int rc;
PRUint64 connid;
int opid;
@@ -574,7 +575,6 @@ sync_send_results( void *arg )
slapi_pblock_get(req->req_pblock, SLAPI_CONN_ID, &connid);
slapi_pblock_get(req->req_pblock, SLAPI_OPERATION_ID, &opid);
slapi_pblock_get(req->req_pblock, SLAPI_CONNECTION, &conn);
- slapi_pblock_get(req->req_pblock, SLAPI_OPERATION, &op);

conn_acq_flag = sync_acquire_connection (conn);
if (conn_acq_flag) {
@@ -587,9 +587,7 @@ sync_send_results( void *arg )

while ( (conn_acq_flag == 0) && !req->req_complete && !plugin_closing) {
/* Check for an abandoned operation */
- Slapi_Operation *op;
- slapi_pblock_get(req->req_pblock, SLAPI_OPERATION, &op);
- if ( op == NULL || slapi_op_abandoned( req->req_pblock ) ) {
+ if ( op == NULL || slapi_is_operation_abandoned( op ) ) {
slapi_log_error(SLAPI_LOG_PLUGIN, "Content Synchronization Search",
"conn=%" NSPRIu64 " op=%d Operation no longer active - terminating\n",
(long long unsigned int)connid, opid);
diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c
index 5ec5e5d..ef4a3f7 100644
--- a/ldap/servers/plugins/sync/sync_util.c
+++ b/ldap/servers/plugins/sync/sync_util.c
@@ -644,18 +644,21 @@ Slapi_PBlock *
sync_pblock_copy(Slapi_PBlock *src)
{
Slapi_Operation *operation;
+ Slapi_Operation *operation_new;
Slapi_Connection *connection;
int *scope;
int *deref;
int *filter_normalized;
char *fstr;
char **attrs, **attrs_dup;
+ char **reqattrs, **reqattrs_dup;
int *attrsonly;
int *isroot;
int *sizelimit;
int *timelimit;
struct slapdplugin *pi;
-
+ ber_int_t msgid;
+ ber_tag_t tag;

slapi_pblock_get( src, SLAPI_OPERATION, &operation );
slapi_pblock_get( src, SLAPI_CONNECTION, &connection );
@@ -664,6 +667,7 @@ sync_pblock_copy(Slapi_PBlock *src)
slapi_pblock_get( src, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
slapi_pblock_get( src, SLAPI_SEARCH_STRFILTER, &fstr );
slapi_pblock_get( src, SLAPI_SEARCH_ATTRS, &attrs );
+ slapi_pblock_get( src, SLAPI_SEARCH_REQATTRS, &reqattrs );
slapi_pblock_get( src, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
slapi_pblock_get( src, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_get( src, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
@@ -671,15 +675,21 @@ sync_pblock_copy(Slapi_PBlock *src)
slapi_pblock_get( src, SLAPI_PLUGIN, &pi);

Slapi_PBlock *dest = slapi_pblock_new();
-
- slapi_pblock_set( dest, SLAPI_OPERATION, operation );
+ operation_new = slapi_operation_new(0);
+ msgid = slapi_operation_get_msgid(operation);
+ slapi_operation_set_msgid(operation_new, msgid);
+ tag = slapi_operation_get_tag(operation);
+ slapi_operation_set_tag(operation_new, tag);
+ slapi_pblock_set( dest, SLAPI_OPERATION, operation_new );
slapi_pblock_set( dest, SLAPI_CONNECTION, connection );
slapi_pblock_set( dest, SLAPI_SEARCH_SCOPE, &scope );
slapi_pblock_set( dest, SLAPI_SEARCH_DEREF, &deref );
slapi_pblock_set( dest, SLAPI_PLUGIN_SYNTAX_FILTER_NORMALIZED, &filter_normalized );
slapi_pblock_set( dest, SLAPI_SEARCH_STRFILTER, slapi_ch_strdup(fstr) );
attrs_dup = slapi_ch_array_dup(attrs);
+ reqattrs_dup = slapi_ch_array_dup(reqattrs);
slapi_pblock_set( dest, SLAPI_SEARCH_ATTRS, attrs_dup );
+ slapi_pblock_set( dest, SLAPI_SEARCH_REQATTRS, reqattrs_dup );
slapi_pblock_set( dest, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
slapi_pblock_set( dest, SLAPI_REQUESTOR_ISROOT, &isroot );
slapi_pblock_set( dest, SLAPI_SEARCH_SIZELIMIT, &sizelimit );
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index c82e6be..1b45c3f 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -52,6 +52,15 @@
#include "fe.h"

int
+slapi_is_operation_abandoned( Slapi_Operation *op )
+{
+ if (op) {
+ return( op->o_status == SLAPI_OP_STATUS_ABANDONED );
+ }
+ return 0;
+}
+
+int
slapi_op_abandoned( Slapi_PBlock *pb )
{
int op_status;
@@ -192,6 +201,11 @@ operation_init(Slapi_Operation *o, int flags)

}

+Slapi_Operation *
+slapi_operation_new(int flags)
+{
+ return (operation_new(flags));
+}
/*
* Allocate a new Slapi_Operation.
* The flag parameter indicates whether the the operation is
@@ -427,6 +441,30 @@ struct slapi_operation_parameters *operation_parameters_new()
return (slapi_operation_parameters *)slapi_ch_calloc (1, sizeof (slapi_operation_parameters));
}

+ber_tag_t
+slapi_operation_get_tag(Slapi_Operation *op)
+{
+ return op->o_tag;
+}
+
+ber_int_t
+slapi_operation_get_msgid(Slapi_Operation *op)
+{
+ return op->o_msgid;
+}
+
+void
+slapi_operation_set_tag(Slapi_Operation *op, ber_tag_t tag)
+{
+ op->o_tag = tag;
+}
+
+void
+slapi_operation_set_msgid(Slapi_Operation *op, ber_int_t msgid)
+{
+ op->o_msgid = msgid;
+}
+
LDAPMod **
copy_mods(LDAPMod **orig_mods)
{
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index d3cc55c..ff991ab 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -1463,6 +1463,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
(*(char ***)value) = pblock->pb_op->o_params.p.p_search.search_gerattrs;
}
break;
+ case SLAPI_SEARCH_REQATTRS:
+ if(pblock->pb_op!=NULL)
+ {
+ (*(char ***)value) = pblock->pb_op->o_searchattrs;
+ }
+ break;
case SLAPI_SEARCH_ATTRSONLY:
if(pblock->pb_op!=NULL)
{
@@ -3104,6 +3110,12 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value )
pblock->pb_op->o_params.p.p_search.search_gerattrs = (char **) value;
}
break;
+ case SLAPI_SEARCH_REQATTRS:
+ if(pblock->pb_op!=NULL)
+ {
+ pblock->pb_op->o_searchattrs = (char **) value;
+ }
+ break;
case SLAPI_SEARCH_ATTRSONLY:
if(pblock->pb_op!=NULL)
{
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index c39d3b3..b83b08a 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5145,16 +5145,22 @@ Slapi_Value *slapi_valueset_find(const Slapi_Attr *a, const Slapi_ValueSet *vs,
* operation routines
*/
int slapi_op_abandoned( Slapi_PBlock *pb );
+int slapi_is_operation_abandoned( Slapi_Operation *op );
unsigned long slapi_op_get_type(Slapi_Operation * op);
void slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag);
void slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag);
int slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag);
+ber_tag_t slapi_operation_get_tag(Slapi_Operation *op);
+ber_int_t slapi_operation_get_msgid(Slapi_Operation *op);
+void slapi_operation_set_tag(Slapi_Operation *op, ber_tag_t tag);
+void slapi_operation_set_msgid(Slapi_Operation *op, ber_int_t msgid);
int slapi_op_reserved(Slapi_PBlock *pb);
void slapi_operation_set_csngen_handler ( Slapi_Operation *op, void *callback );
void slapi_operation_set_replica_attr_handler ( Slapi_Operation *op, void *callback );
int slapi_operation_get_replica_attr ( Slapi_PBlock *pb, Slapi_Operation *op, const char *type, void *value );
char *slapi_op_type_to_string(unsigned long type);
int slapi_op_internal( Slapi_PBlock *pb );
+Slapi_Operation *slapi_operation_new(int flags);

/*
* connection routines
@@ -7157,6 +7163,7 @@ typedef struct slapi_plugindesc {
#define SLAPI_SEARCH_STRFILTER 115
#define SLAPI_SEARCH_ATTRS 116
#define SLAPI_SEARCH_GERATTRS 1160
+#define SLAPI_SEARCH_REQATTRS 1161
#define SLAPI_SEARCH_ATTRSONLY 117
#define SLAPI_SEARCH_IS_AND 118


--
389 commits mailing list
389-commits@lists.fedoraproject.org
https://admin.fedoraproject.org/mailman/listinfo/389-commits

No comments:

Post a Comment