mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-24 13:24:56 +08:00
SyncRepl is changed to share the following routnines :
slap_mods_opattrs(), slap_mods_check(), slap_mods2entry()
This commit is contained in:
parent
132f738059
commit
2b803b0459
@ -280,8 +280,8 @@ do_add( Operation *op, SlapReply *rs )
|
||||
}
|
||||
}
|
||||
|
||||
rs->sr_err = slap_mods2entry( modlist, &e, repl_user, &rs->sr_text,
|
||||
textbuf, textlen );
|
||||
rs->sr_err = slap_mods2entry( modlist, &e, repl_user, 0,
|
||||
&rs->sr_text, textbuf, textlen );
|
||||
if( rs->sr_err != LDAP_SUCCESS ) {
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
@ -392,6 +392,7 @@ slap_mods2entry(
|
||||
Modifications *mods,
|
||||
Entry **e,
|
||||
int repl_user,
|
||||
int dup,
|
||||
const char **text,
|
||||
char *textbuf, size_t textlen )
|
||||
{
|
||||
@ -403,7 +404,12 @@ slap_mods2entry(
|
||||
for( ; mods != NULL; mods = mods->sml_next ) {
|
||||
Attribute *attr;
|
||||
|
||||
assert( mods->sml_op == LDAP_MOD_ADD );
|
||||
#ifdef LDAP_SYNCREPL
|
||||
if ( !repl_user )
|
||||
#endif
|
||||
{
|
||||
assert( mods->sml_op == LDAP_MOD_ADD );
|
||||
}
|
||||
assert( mods->sml_desc != NULL );
|
||||
|
||||
attr = attr_find( (*e)->e_attrs, mods->sml_desc );
|
||||
@ -522,16 +528,37 @@ slap_mods2entry(
|
||||
|
||||
/* move ad to attr structure */
|
||||
attr->a_desc = mods->sml_desc;
|
||||
mods->sml_desc = NULL;
|
||||
if ( !dup )
|
||||
mods->sml_desc = NULL;
|
||||
|
||||
/* move values to attr structure */
|
||||
/* should check for duplicates */
|
||||
attr->a_vals = mods->sml_values;
|
||||
mods->sml_values = NULL;
|
||||
if ( dup ) {
|
||||
int i;
|
||||
for ( i = 0; mods->sml_values[i].bv_val; i++ ) ;
|
||||
attr->a_vals = (BerVarray) ch_calloc( i+1, sizeof( BerValue ));
|
||||
for ( i = 0; mods->sml_values[i].bv_val; i++ )
|
||||
ber_dupbv( &attr->a_vals[i], &mods->sml_values[i] );
|
||||
attr->a_vals[i].bv_len = 0;
|
||||
attr->a_vals[i].bv_val = NULL;
|
||||
} else {
|
||||
attr->a_vals = mods->sml_values;
|
||||
mods->sml_values = NULL;
|
||||
}
|
||||
|
||||
if ( mods->sml_nvalues ) {
|
||||
attr->a_nvals = mods->sml_nvalues;
|
||||
mods->sml_nvalues = NULL;
|
||||
if ( dup ) {
|
||||
int i;
|
||||
for ( i = 0; mods->sml_nvalues[i].bv_val; i++ ) ;
|
||||
attr->a_nvals = (BerVarray) ch_calloc( i+1, sizeof( BerValue ));
|
||||
for ( i = 0; mods->sml_nvalues[i].bv_val; i++ )
|
||||
ber_dupbv( &attr->a_nvals[i], &mods->sml_nvalues[i] );
|
||||
attr->a_nvals[i].bv_len = 0;
|
||||
attr->a_nvals[i].bv_val = NULL;
|
||||
} else {
|
||||
attr->a_nvals = mods->sml_nvalues;
|
||||
mods->sml_nvalues = NULL;
|
||||
}
|
||||
} else {
|
||||
attr->a_nvals = attr->a_vals;
|
||||
}
|
||||
@ -543,6 +570,78 @@ slap_mods2entry(
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
slap_entry2mods(
|
||||
Entry *e,
|
||||
Modifications **mods,
|
||||
const char **text
|
||||
)
|
||||
{
|
||||
Modifications *modhead = NULL;
|
||||
Modifications *mod;
|
||||
Modifications **modtail = &modhead;
|
||||
Attribute *a_new;
|
||||
AttributeDescription *a_new_desc;
|
||||
int i, count, rc;
|
||||
|
||||
a_new = e->e_attrs;
|
||||
|
||||
while ( a_new != NULL ) {
|
||||
a_new_desc = a_new->a_desc;
|
||||
mod = (Modifications *) malloc( sizeof( Modifications ));
|
||||
|
||||
if ( a_new_desc != slap_schema.si_ad_queryid )
|
||||
mod->sml_op = LDAP_MOD_REPLACE;
|
||||
else
|
||||
mod->sml_op = LDAP_MOD_ADD;
|
||||
|
||||
ber_dupbv( &mod->sml_type, &a_new_desc->ad_cname );
|
||||
|
||||
for ( count = 0; a_new->a_vals[count].bv_val; count++ );
|
||||
|
||||
mod->sml_bvalues = (struct berval*) malloc(
|
||||
(count+1) * sizeof( struct berval) );
|
||||
|
||||
mod->sml_nvalues = (struct berval*) malloc(
|
||||
(count+1) * sizeof( struct berval) );
|
||||
|
||||
for ( i = 0; i < count; i++ ) {
|
||||
ber_dupbv(mod->sml_bvalues+i, a_new->a_vals+i);
|
||||
if ( a_new->a_desc->ad_type->sat_equality &&
|
||||
a_new->a_desc->ad_type->sat_equality->smr_normalize ) {
|
||||
rc = a_new->a_desc->ad_type->sat_equality->smr_normalize(
|
||||
0,
|
||||
a_new->a_desc->ad_type->sat_syntax,
|
||||
a_new->a_desc->ad_type->sat_equality,
|
||||
a_new->a_vals+i, mod->sml_nvalues+i, NULL );
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ber_dupbv( mod->sml_nvalues+i, a_new->a_vals+i );
|
||||
}
|
||||
}
|
||||
|
||||
mod->sml_bvalues[count].bv_val = 0;
|
||||
mod->sml_bvalues[count].bv_len = 0;
|
||||
|
||||
mod->sml_nvalues[count].bv_val = 0;
|
||||
mod->sml_nvalues[count].bv_len = 0;
|
||||
|
||||
mod->sml_desc = NULL;
|
||||
slap_bv2ad(&mod->sml_type, &mod->sml_desc, text);
|
||||
mod->sml_next =NULL;
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
a_new = a_new->a_next;
|
||||
}
|
||||
|
||||
mods = &modhead;
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef LDAP_SLAPI
|
||||
static void initAddPlugin( Operation *op,
|
||||
struct berval *dn, Entry *e, int manageDSAit )
|
||||
|
@ -704,10 +704,19 @@ int slap_mods_opattrs(
|
||||
int mop = op->o_tag == LDAP_REQ_ADD
|
||||
? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
|
||||
|
||||
#ifdef LDAP_SYNCREPL
|
||||
syncinfo_t *si = op->o_si;
|
||||
#endif
|
||||
|
||||
assert( modtail != NULL );
|
||||
assert( *modtail == NULL );
|
||||
|
||||
if( SLAP_LASTMOD(op->o_bd) ) {
|
||||
#ifdef LDAP_SYNCREPL
|
||||
if ( SLAP_LASTMOD(op->o_bd) && ( !si || si->lastmod == LASTMOD_GEN ))
|
||||
#else
|
||||
if ( SLAP_LASTMOD(op->o_bd) )
|
||||
#endif
|
||||
{
|
||||
struct tm *ltm;
|
||||
time_t now = slap_get_time();
|
||||
|
||||
@ -762,25 +771,36 @@ int slap_mods_opattrs(
|
||||
modtail = &mod->sml_next;
|
||||
}
|
||||
|
||||
if( SLAP_LASTMOD(op->o_bd) ) {
|
||||
#ifdef LDAP_SYNCREPL
|
||||
if ( SLAP_LASTMOD(op->o_bd) && ( !si || si->lastmod == LASTMOD_GEN ))
|
||||
#else
|
||||
if ( SLAP_LASTMOD(op->o_bd) )
|
||||
#endif
|
||||
{
|
||||
char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
|
||||
|
||||
tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
|
||||
tmpval.bv_val = uuidbuf;
|
||||
#ifdef LDAP_SYNCREPL
|
||||
if ( !si ) {
|
||||
#endif
|
||||
tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
|
||||
tmpval.bv_val = uuidbuf;
|
||||
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_entryUUID;
|
||||
mod->sml_values =
|
||||
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], &tmpval );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = NULL;
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_entryUUID;
|
||||
mod->sml_values =
|
||||
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], &tmpval );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = NULL;
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
#ifdef LDAP_SYNCREPL
|
||||
}
|
||||
#endif
|
||||
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
@ -815,7 +835,12 @@ int slap_mods_opattrs(
|
||||
}
|
||||
}
|
||||
|
||||
if( SLAP_LASTMOD(op->o_bd) ) {
|
||||
#ifdef LDAP_SYNCREPL
|
||||
if ( SLAP_LASTMOD(op->o_bd) && ( !si || si->lastmod == LASTMOD_GEN ))
|
||||
#else
|
||||
if ( SLAP_LASTMOD(op->o_bd) )
|
||||
#endif
|
||||
{
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
|
@ -95,7 +95,10 @@ LDAP_SLAPD_F (MatchingRule *) ad_mr(
|
||||
* add.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e,
|
||||
int repl_user, const char **text, char *textbuf, size_t textlen ));
|
||||
int repl_user, int dup, const char **text, char *textbuf, size_t textlen ));
|
||||
|
||||
LDAP_SLAPD_F (int) slap_entry2mods LDAP_P(( Entry *e,
|
||||
Modifications **mods, const char **text ));
|
||||
|
||||
/*
|
||||
* at.c
|
||||
|
@ -1967,6 +1967,10 @@ typedef struct slap_op {
|
||||
#define get_assertion(op) ((op)->o_assertion)
|
||||
ValuesReturnFilter *o_vrFilter; /* ValuesReturnFilter */
|
||||
|
||||
#ifdef LDAP_SYNCREPL
|
||||
syncinfo_t* o_si;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CACHING
|
||||
char o_caching_on;
|
||||
#endif /*LDAP_CACHING */
|
||||
|
@ -302,8 +302,8 @@ freeMods( Modifications *ml )
|
||||
for ( ; ml != NULL; ml = next ) {
|
||||
next = ml->sml_next;
|
||||
|
||||
slapi_ch_free( (void **)&ml->sml_bvalues );
|
||||
slapi_ch_free( (void **)&ml->sml_nvalues );
|
||||
if ( ml->sml_bvalues ) slapi_ch_free( (void **)&ml->sml_bvalues );
|
||||
if ( ml->sml_nvalues ) slapi_ch_free( (void **)&ml->sml_nvalues );
|
||||
slapi_ch_free( (void **)&ml );
|
||||
}
|
||||
}
|
||||
@ -441,7 +441,7 @@ LDAPModToEntry(
|
||||
* in servers/slapd/add.c
|
||||
*/
|
||||
rc = slap_mods2entry( modlist, &pEntry, repl_user,
|
||||
&text, textbuf, textlen );
|
||||
0, &text, textbuf, textlen );
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -38,19 +38,7 @@
|
||||
#include "ldap_rq.h"
|
||||
|
||||
static void
|
||||
syncrepl_del_nonpresent( syncinfo_t *, LDAP *, Operation * );
|
||||
|
||||
static int
|
||||
slap_mods_check_syncrepl( syncinfo_t *, Operation *, Modifications **,
|
||||
const char **, char *, size_t, void *ctx );
|
||||
|
||||
static int
|
||||
slap_mods_opattrs_syncrepl( syncinfo_t *, Operation *, Modifications *,
|
||||
Modifications **, const char **, char *, size_t );
|
||||
|
||||
static int
|
||||
slap_mods2entry_syncrepl( syncinfo_t *, Modifications *, Entry **, int,
|
||||
const char **, char *, size_t );
|
||||
syncrepl_del_nonpresent( LDAP *, Operation * );
|
||||
|
||||
/* callback functions */
|
||||
static int cookie_callback( struct slap_op *, struct slap_rep * );
|
||||
@ -375,6 +363,7 @@ do_syncrepl(
|
||||
op.o_tmpmemctx = memctx;
|
||||
op.o_tmpmfuncs = &sl_mfuncs;
|
||||
|
||||
op.o_si = si;
|
||||
op.o_tag = LDAP_REQ_SEARCH;
|
||||
op.o_dn = si->updatedn;
|
||||
op.o_ndn = si->updatedn;
|
||||
@ -549,7 +538,7 @@ do_syncrepl(
|
||||
if ( syncCookie.bv_len ) {
|
||||
syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie);
|
||||
}
|
||||
syncrepl_del_nonpresent( si, ld, &op );
|
||||
syncrepl_del_nonpresent( ld, &op );
|
||||
if ( ctrl_ber )
|
||||
ber_free( ctrl_ber, 1 );
|
||||
goto done;
|
||||
@ -565,7 +554,7 @@ do_syncrepl(
|
||||
ber_scanf( res_ber, "{e" /*"}"*/, &syncstate );
|
||||
|
||||
if ( syncstate == LDAP_SYNC_REFRESH_DONE ) {
|
||||
syncrepl_del_nonpresent( si, ld, &op );
|
||||
syncrepl_del_nonpresent( ld, &op );
|
||||
} else if ( syncstate != LDAP_SYNC_NEW_COOKIE ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( OPERATION, ERR,
|
||||
@ -700,6 +689,12 @@ syncrepl_message_to_entry(
|
||||
|
||||
ber_tag_t tag;
|
||||
|
||||
Modifications *prevml = NULL;
|
||||
Modifications *nextml = NULL;
|
||||
Modifications *ml = NULL;
|
||||
AttributeDescription** descs;
|
||||
int i;
|
||||
|
||||
*modlist = NULL;
|
||||
|
||||
if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) {
|
||||
@ -820,8 +815,45 @@ syncrepl_message_to_entry(
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = slap_mods_check_syncrepl( si, op, modlist,
|
||||
&text, txtbuf, textlen, NULL );
|
||||
ml = *modlist;
|
||||
while ( ml != NULL ) {
|
||||
AttributeDescription *ad = NULL;
|
||||
rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, &text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
e = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ad = ml->sml_desc;
|
||||
ml->sml_desc = NULL;
|
||||
|
||||
if ( si->lastmod == LASTMOD_REQ ) {
|
||||
descs = del_descs_lastmod;
|
||||
} else {
|
||||
descs = del_descs;
|
||||
}
|
||||
|
||||
for ( i = 0; descs[i] != NULL; i++ ) {
|
||||
if ( ad == descs[i] ) {
|
||||
if ( prevml == NULL ) {
|
||||
modlist = &ml->sml_next;
|
||||
prevml = NULL;
|
||||
} else {
|
||||
prevml->sml_next = ml->sml_next;
|
||||
}
|
||||
slap_mod_free( &ml->sml_mod, 0 );
|
||||
nextml = ml->sml_next;
|
||||
free( ml );
|
||||
ml = nextml;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
prevml = ml;
|
||||
ml = ml->sml_next;
|
||||
}
|
||||
|
||||
rc = slap_mods_check( *modlist, 1, &text, txtbuf, textlen, NULL );
|
||||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
@ -834,8 +866,8 @@ syncrepl_message_to_entry(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = slap_mods_opattrs_syncrepl( si, op, *modlist, modtail,
|
||||
&text,txtbuf, textlen );
|
||||
rc = slap_mods_opattrs( op, *modlist, modtail,
|
||||
&text,txtbuf, textlen );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
@ -848,7 +880,7 @@ syncrepl_message_to_entry(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = slap_mods2entry_syncrepl( si, *modlist, &e, 1, &text, txtbuf, textlen);
|
||||
rc = slap_mods2entry( *modlist, &e, 1, 1, &text, txtbuf, textlen);
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( OPERATION, ERR,
|
||||
@ -1044,12 +1076,12 @@ syncrepl_entry(
|
||||
|
||||
static void
|
||||
syncrepl_del_nonpresent(
|
||||
syncinfo_t *si,
|
||||
LDAP *ld,
|
||||
Operation *op
|
||||
)
|
||||
{
|
||||
Backend* be = op->o_bd;
|
||||
syncinfo_t *si = op->o_si;
|
||||
slap_callback cb;
|
||||
struct berval base_bv = {0, NULL};
|
||||
Filter *filter;
|
||||
@ -1344,8 +1376,7 @@ syncrepl_updateCookie(
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
|
||||
rc = slap_mods_check_syncrepl( si, op, &modlist,
|
||||
&text, txtbuf, textlen, NULL );
|
||||
rc = slap_mods_check( modlist, 1, &text, txtbuf, textlen, NULL );
|
||||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
@ -1358,8 +1389,8 @@ syncrepl_updateCookie(
|
||||
}
|
||||
|
||||
op->o_tag = LDAP_REQ_ADD;
|
||||
rc = slap_mods_opattrs_syncrepl( si, op, modlist, modtail,
|
||||
&text,txtbuf, textlen );
|
||||
rc = slap_mods_opattrs( op, modlist, modtail,
|
||||
&text,txtbuf, textlen );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
@ -1380,7 +1411,7 @@ syncrepl_updateCookie(
|
||||
|
||||
e->e_attrs = NULL;
|
||||
|
||||
rc = slap_mods2entry_syncrepl( si, modlist, &e, 1, &text, txtbuf, textlen );
|
||||
rc = slap_mods2entry( modlist, &e, 1, 1, &text, txtbuf, textlen );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
@ -1462,481 +1493,6 @@ done :
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int slap_mods_check_syncrepl(
|
||||
syncinfo_t* si,
|
||||
Operation *op,
|
||||
Modifications **mlp,
|
||||
const char **text,
|
||||
char *textbuf,
|
||||
size_t textlen,
|
||||
void *ctx )
|
||||
{
|
||||
int rc;
|
||||
Backend *be = op->o_bd;
|
||||
AttributeDescription** descs;
|
||||
int i;
|
||||
Modifications *prevml = NULL;
|
||||
Modifications *nextml = NULL;
|
||||
Modifications *ml = *mlp;
|
||||
|
||||
while ( ml != NULL ) {
|
||||
AttributeDescription *ad = NULL;
|
||||
|
||||
/* convert to attribute description */
|
||||
rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
snprintf( textbuf, textlen, "%s: %s",
|
||||
ml->sml_type.bv_val, *text );
|
||||
*text = textbuf;
|
||||
return rc;
|
||||
}
|
||||
|
||||
ad = ml->sml_desc;
|
||||
|
||||
if ( si->lastmod == LASTMOD_REQ ) {
|
||||
descs = del_descs_lastmod;
|
||||
} else {
|
||||
descs = del_descs;
|
||||
}
|
||||
|
||||
for ( i = 0; descs[i] != NULL; i++ ) {
|
||||
if ( ad == descs[i] ) {
|
||||
if ( prevml == NULL ) {
|
||||
mlp = &ml->sml_next;
|
||||
prevml = NULL;
|
||||
} else {
|
||||
prevml->sml_next = ml->sml_next;
|
||||
}
|
||||
slap_mod_free( &ml->sml_mod, 0 );
|
||||
nextml = ml->sml_next;
|
||||
free( ml );
|
||||
ml = nextml;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( slap_syntax_is_binary( ad->ad_type->sat_syntax )
|
||||
&& !slap_ad_is_binary( ad )) {
|
||||
/* attribute requires binary transfer */
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: requires ;binary transfer",
|
||||
ml->sml_type.bv_val );
|
||||
*text = textbuf;
|
||||
return LDAP_UNDEFINED_TYPE;
|
||||
}
|
||||
|
||||
if( !slap_syntax_is_binary( ad->ad_type->sat_syntax )
|
||||
&& slap_ad_is_binary( ad )) {
|
||||
/* attribute requires binary transfer */
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: disallows ;binary transfer",
|
||||
ml->sml_type.bv_val );
|
||||
*text = textbuf;
|
||||
return LDAP_UNDEFINED_TYPE;
|
||||
}
|
||||
|
||||
if( slap_ad_is_tag_range( ad )) {
|
||||
/* attribute requires binary transfer */
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: inappropriate use of tag range option",
|
||||
ml->sml_type.bv_val );
|
||||
*text = textbuf;
|
||||
return LDAP_UNDEFINED_TYPE;
|
||||
}
|
||||
|
||||
if ( is_at_obsolete( ad->ad_type ) &&
|
||||
( ml->sml_op == LDAP_MOD_ADD || ml->sml_values != NULL ) ) {
|
||||
/*
|
||||
* attribute is obsolete,
|
||||
* only allow replace/delete with no values
|
||||
*/
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: attribute is obsolete",
|
||||
ml->sml_type.bv_val );
|
||||
*text = textbuf;
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
/*
|
||||
* check values
|
||||
*/
|
||||
if( ml->sml_values != NULL ) {
|
||||
ber_len_t nvals;
|
||||
slap_syntax_validate_func *validate =
|
||||
ad->ad_type->sat_syntax->ssyn_validate;
|
||||
slap_syntax_transform_func *pretty =
|
||||
ad->ad_type->sat_syntax->ssyn_pretty;
|
||||
|
||||
if( !pretty && !validate ) {
|
||||
*text = "no validator for syntax";
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: no validator for syntax %s",
|
||||
ml->sml_type.bv_val,
|
||||
ad->ad_type->sat_syntax->ssyn_oid );
|
||||
*text = textbuf;
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
/*
|
||||
* check that each value is valid per syntax
|
||||
* and pretty if appropriate
|
||||
*/
|
||||
for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) {
|
||||
struct berval pval = {0, NULL};
|
||||
if( pretty ) {
|
||||
rc = pretty( ad->ad_type->sat_syntax,
|
||||
&ml->sml_values[nvals], &pval, ctx );
|
||||
} else {
|
||||
rc = validate( ad->ad_type->sat_syntax,
|
||||
&ml->sml_values[nvals] );
|
||||
}
|
||||
|
||||
if( rc != 0 ) {
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: value #%ld invalid per syntax",
|
||||
ml->sml_type.bv_val, (long) nvals );
|
||||
*text = textbuf;
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
if( pretty ) {
|
||||
ber_memfree( ml->sml_values[nvals].bv_val );
|
||||
ml->sml_values[nvals] = pval;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* a rough single value check... an additional check is needed
|
||||
* to catch add of single value to existing single valued attribute
|
||||
*/
|
||||
if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
|
||||
&& nvals > 1 && is_at_single_value( ad->ad_type )) {
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: multiple values provided",
|
||||
ml->sml_type.bv_val );
|
||||
*text = textbuf;
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
if( nvals && ad->ad_type->sat_equality &&
|
||||
ad->ad_type->sat_equality->smr_normalize ) {
|
||||
ml->sml_nvalues = ch_malloc( (nvals+1)*sizeof(struct berval) );
|
||||
for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) {
|
||||
rc = ad->ad_type->sat_equality->smr_normalize( 0,
|
||||
ad->ad_type->sat_syntax, ad->ad_type->sat_equality,
|
||||
&ml->sml_values[nvals], &ml->sml_nvalues[nvals], ctx );
|
||||
if( rc ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( OPERATION, DETAIL1,
|
||||
"str2entry: NULL (ssyn_normalize %d)\n", rc, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= str2entry NULL (ssyn_normalize %d)\n", rc, 0, 0 );
|
||||
#endif
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: value #%ld normalization failed",
|
||||
ml->sml_type.bv_val, (long) nvals );
|
||||
*text = textbuf;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
ml->sml_nvalues[nvals].bv_val = NULL;
|
||||
ml->sml_nvalues[nvals].bv_len = 0;
|
||||
}
|
||||
}
|
||||
prevml = ml;
|
||||
ml = ml->sml_next;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int slap_mods_opattrs_syncrepl(
|
||||
syncinfo_t *si,
|
||||
Operation *op,
|
||||
Modifications *mods,
|
||||
Modifications **modtail,
|
||||
const char **text,
|
||||
char *textbuf, size_t textlen )
|
||||
{
|
||||
struct berval name = {0, NULL};
|
||||
struct berval timestamp = {0, NULL};
|
||||
struct berval csn = {0, NULL};
|
||||
struct berval nname = {0, NULL};
|
||||
char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
|
||||
char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
|
||||
Modifications *mod;
|
||||
Backend *be = op->o_bd;
|
||||
|
||||
int mop = LDAP_MOD_REPLACE;
|
||||
|
||||
assert( modtail != NULL );
|
||||
assert( *modtail == NULL );
|
||||
|
||||
if( si->lastmod == LASTMOD_GEN ) {
|
||||
struct tm *ltm;
|
||||
time_t now = slap_get_time();
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &gmtime_mutex );
|
||||
ltm = gmtime( &now );
|
||||
lutil_gentime( timebuf, sizeof(timebuf), ltm );
|
||||
|
||||
csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), 0, 0 );
|
||||
ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
|
||||
csn.bv_val = csnbuf;
|
||||
|
||||
timestamp.bv_val = timebuf;
|
||||
timestamp.bv_len = strlen(timebuf);
|
||||
|
||||
if( op->o_dn.bv_len == 0 ) {
|
||||
name.bv_val = SLAPD_ANONYMOUS;
|
||||
name.bv_len = sizeof(SLAPD_ANONYMOUS)-1;
|
||||
nname = name;
|
||||
} else {
|
||||
name = op->o_dn;
|
||||
nname = op->o_ndn;
|
||||
}
|
||||
}
|
||||
|
||||
if( op->o_tag == LDAP_REQ_ADD ) {
|
||||
struct berval tmpval = {0, NULL};
|
||||
|
||||
if( global_schemacheck ) {
|
||||
int rc = mods_structural_class( mods, &tmpval,
|
||||
text, textbuf, textlen );
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
|
||||
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], &tmpval );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_nvalues[0], &tmpval );
|
||||
mod->sml_nvalues[1].bv_len = 0;
|
||||
mod->sml_nvalues[1].bv_val = NULL;
|
||||
assert( mod->sml_nvalues[0].bv_val );
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
}
|
||||
|
||||
if( si->lastmod == LASTMOD_GEN ) {
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_creatorsName;
|
||||
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], &name );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_nvalues[0], &nname );
|
||||
mod->sml_nvalues[1].bv_len = 0;
|
||||
mod->sml_nvalues[1].bv_val = NULL;
|
||||
assert( mod->sml_nvalues[0].bv_val );
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_createTimestamp;
|
||||
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], ×tamp );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = NULL;
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
}
|
||||
}
|
||||
|
||||
if( si->lastmod == LASTMOD_GEN ) {
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_entryCSN;
|
||||
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], &csn );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = NULL;
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_modifiersName;
|
||||
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], &name );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_nvalues[0], &nname );
|
||||
mod->sml_nvalues[1].bv_len = 0;
|
||||
mod->sml_nvalues[1].bv_val = NULL;
|
||||
assert( mod->sml_nvalues[0].bv_val );
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
|
||||
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
|
||||
mod->sml_op = mop;
|
||||
mod->sml_type.bv_val = NULL;
|
||||
mod->sml_desc = slap_schema.si_ad_modifyTimestamp;
|
||||
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
|
||||
ber_dupbv( &mod->sml_values[0], ×tamp );
|
||||
mod->sml_values[1].bv_len = 0;
|
||||
mod->sml_values[1].bv_val = NULL;
|
||||
assert( mod->sml_values[0].bv_val );
|
||||
mod->sml_nvalues = NULL;
|
||||
*modtail = mod;
|
||||
modtail = &mod->sml_next;
|
||||
}
|
||||
|
||||
*modtail = NULL;
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int slap_mods2entry_syncrepl(
|
||||
syncinfo_t *si,
|
||||
Modifications *mods,
|
||||
Entry **e,
|
||||
int repl_user,
|
||||
const char **text,
|
||||
char *textbuf, size_t textlen )
|
||||
{
|
||||
Attribute **tail = &(*e)->e_attrs;
|
||||
assert( *tail == NULL );
|
||||
|
||||
*text = textbuf;
|
||||
|
||||
for( ; mods != NULL; mods = mods->sml_next ) {
|
||||
Attribute *attr;
|
||||
|
||||
assert( mods->sml_desc != NULL );
|
||||
|
||||
attr = attr_find( (*e)->e_attrs, mods->sml_desc );
|
||||
|
||||
if( attr != NULL ) {
|
||||
#define SLURPD_FRIENDLY
|
||||
#ifdef SLURPD_FRIENDLY
|
||||
ber_len_t i,j;
|
||||
|
||||
if( !repl_user ) {
|
||||
snprintf( textbuf, textlen,
|
||||
"attribute '%s' provided more than once",
|
||||
mods->sml_desc->ad_cname.bv_val );
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
}
|
||||
|
||||
for( i=0; attr->a_vals[i].bv_val; i++ ) {
|
||||
/* count them */
|
||||
}
|
||||
for( j=0; mods->sml_values[j].bv_val; j++ ) {
|
||||
/* count them */
|
||||
}
|
||||
j++; /* NULL */
|
||||
|
||||
attr->a_vals = ch_realloc( attr->a_vals,
|
||||
sizeof( struct berval ) * (i+j) );
|
||||
|
||||
/* should check for duplicates */
|
||||
|
||||
AC_MEMCPY( &attr->a_vals[i], mods->sml_values,
|
||||
sizeof( struct berval ) * j );
|
||||
|
||||
if( attr->a_nvals ) {
|
||||
attr->a_nvals = ch_realloc( attr->a_nvals,
|
||||
sizeof( struct berval ) * (i+j) );
|
||||
|
||||
AC_MEMCPY( &attr->a_nvals[i], mods->sml_nvalues,
|
||||
sizeof( struct berval ) * j );
|
||||
|
||||
/* trim the mods array */
|
||||
ch_free( mods->sml_nvalues );
|
||||
mods->sml_nvalues = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
#else
|
||||
snprintf( textbuf, textlen,
|
||||
"attribute '%s' provided more than once",
|
||||
mods->sml_desc->ad_cname.bv_val );
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
#endif
|
||||
}
|
||||
|
||||
if( mods->sml_values[1].bv_val != NULL ) {
|
||||
/* check for duplicates */
|
||||
int i, j;
|
||||
MatchingRule *mr = mods->sml_desc->ad_type->sat_equality;
|
||||
|
||||
/* check if the values we're adding already exist */
|
||||
if( mr == NULL || !mr->smr_match ) {
|
||||
for ( i = 0; mods->sml_bvalues[i].bv_val != NULL; i++ ) {
|
||||
/* test asserted values against themselves */
|
||||
for( j = 0; j < i; j++ ) {
|
||||
if ( bvmatch( &mods->sml_bvalues[i],
|
||||
&mods->sml_bvalues[j] ) ) {
|
||||
/* value exists already */
|
||||
snprintf( textbuf, textlen,
|
||||
"%s: value #%d provided more than once",
|
||||
mods->sml_desc->ad_cname.bv_val, j );
|
||||
return LDAP_TYPE_OR_VALUE_EXISTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
int rc;
|
||||
const char *text = NULL;
|
||||
char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
|
||||
|
||||
rc = modify_check_duplicates( mods->sml_desc, mr,
|
||||
NULL, mods->sml_bvalues, 0,
|
||||
&text, textbuf, sizeof( textbuf ) );
|
||||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attr = ch_calloc( 1, sizeof(Attribute) );
|
||||
|
||||
/* move ad to attr structure */
|
||||
attr->a_desc = mods->sml_desc;
|
||||
|
||||
/* move values to attr structure */
|
||||
/* should check for duplicates */
|
||||
attr->a_vals = mods->sml_values;
|
||||
|
||||
attr->a_nvals = mods->sml_nvalues;
|
||||
|
||||
*tail = attr;
|
||||
tail = &attr->a_next;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
avl_ber_bvfree( void *bv )
|
||||
{
|
||||
|
@ -215,12 +215,23 @@ slap_mods2entry(
|
||||
Modifications *mods,
|
||||
Entry **e,
|
||||
int repl_user,
|
||||
int dup,
|
||||
const char **text,
|
||||
char *textbuf, size_t textlen )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
slap_entry2mods(
|
||||
Entry *e,
|
||||
Modifications **mods,
|
||||
const char **text
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len,
|
||||
char *user_realm, struct berval *dn, int flags )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user