summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/entry.c
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2010-01-22 09:47:52 -0800
committerNoriko Hosoi <nhosoi@jiji.localdomain>2010-01-22 10:36:16 -0800
commitb5e653a844af60596f9bc6b16349ee902ddb51f5 (patch)
treed22f47113e303de236e9a9b01376cb6e3d14486f /ldap/servers/slapd/entry.c
parent4d93699a71acb061c5787d2b8b61a0417ce02808 (diff)
downloadds-b5e653a844af60596f9bc6b16349ee902ddb51f5.tar.gz
ds-b5e653a844af60596f9bc6b16349ee902ddb51f5.tar.xz
ds-b5e653a844af60596f9bc6b16349ee902ddb51f5.zip
Allow modrdn to move subtree and rename non-leaf node
This patch includes - replacing the entrydn index with the entryrdn index - replacing a full DN in each entry in the DB with an RDN - extending Slapi_Entry, entry2str, and str2entry to absorb the changes made on the entry - adding DN/RDN helper functions - adding DN cache - adding a utility and a migration script to convert the DN format database to the RDN format - extending a database dump utility dbscan to support the entryrdn - slapi_dn_syntax_check by nkinder@redhat.com is added to check the dn before modify operations - big fix for 171338 - Enhancement: winsync modrdn not synced In addition to the above, compile warnings and memory leaks found in testing the new feature are fixed. For more details, see the feature design document at: http://directory.fedoraproject.org/wiki/Subtree_Rename and bugzilla at: https://bugzilla.redhat.com/show_bug.cgi?id=171338
Diffstat (limited to 'ldap/servers/slapd/entry.c')
-rw-r--r--ldap/servers/slapd/entry.c332
1 files changed, 300 insertions, 32 deletions
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index fea08814..db641b63 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -150,9 +150,9 @@ str2entry_state_information_from_type(char *s,CSNSet **csnset,CSN **attributedel
}
}
-
+/* dn is not consumed. Caller needs to free it. */
static Slapi_Entry *
-str2entry_fast( char *s, int flags, int read_stateinfo )
+str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
{
Slapi_Entry *e;
char *next, *ptype=NULL;
@@ -165,17 +165,24 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
CSN *maxcsn = NULL;
/*
- * In string format, an entry looks like this:
+ * In string format, an entry looks like either of these:
*
* dn: <dn>\n
* [<attr>:[:] <value>\n]
* [<tab><continuedvalue>\n]*
* ...
*
+ * rdn: <rdn>\n
+ * [<attr>:[:] <value>\n]
+ * [<tab><continuedvalue>\n]*
+ * ...
+ *
* If a double colon is used after a type, it means the
* following value is encoded as a base 64 string. This
* happens if the value contains a non-printing character
* or newline.
+ *
+ * In case an entry starts with rdn:, dn must be provided.
*/
LDAPDebug( LDAP_DEBUG_TRACE, "=> str2entry_fast\n", 0, 0, 0 );
@@ -183,7 +190,7 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
e = slapi_entry_alloc();
slapi_entry_init(e,NULL,NULL);
- /* dn + attributes */
+ /* dn|rdn + attributes */
next = s;
/* get the read lock of name2asi for performance purpose.
@@ -260,17 +267,24 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
a = NULL;
}
- if ( strcasecmp( type, "dn" ) == 0 )
- {
- if ( slapi_entry_get_dn_const(e)!=NULL )
- {
+ if ( dn ) {
+ if ( NULL == slapi_entry_get_dn_const( e )) {
+ slapi_entry_set_dn( e, slapi_ch_strdup( dn ));
+ }
+ if ( NULL == slapi_entry_get_rdn_const( e )) {
+ slapi_entry_set_rdn( e, (char *)dn );
+ }
+ }
+ if ( strcasecmp( type, "dn" ) == 0 ) {
+ if ( slapi_entry_get_dn_const(e)!=NULL ) {
char ebuf[ BUFSIZ ];
- LDAPDebug( LDAP_DEBUG_ANY,
- "str2entry_fast: entry has multiple dns \"%s\" and \"%s\" (second ignored)\n",
- 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);
+ LDAPDebug( LDAP_DEBUG_TRACE,
+ "str2entry_fast: entry has multiple dns \"%s\" and "
+ "\"%s\" (second ignored)\n",
+ 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_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
continue;
}
@@ -278,9 +292,20 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
- continue;
+ continue;
+ }
+
+ if ( strcasecmp( type, "rdn" ) == 0 ) {
+ if ( NULL == slapi_entry_get_rdn_const( e )) {
+ slapi_entry_set_rdn( e, valuecharptr );
+ }
+ /* the memory below was not allocated by the slapi_ch_ functions */
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ continue;
}
+
/* retrieve uniqueid */
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
@@ -574,8 +599,9 @@ entry_attrs_find(entry_attrs *ea,char *type)
if flags contains SLAPI_STR2ENTRY_REMOVEDUPVALS.
*/
+/* dn is not consumed. Caller needs to free it. */
static Slapi_Entry *
-str2entry_dupcheck( char *s, int flags, int read_stateinfo )
+str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
{
Slapi_Entry *e;
str2entry_attr stack_attrs[STR2ENTRY_SMALL_BUFFER_SIZE];
@@ -630,7 +656,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( (retmalloc = ldif_parse_line( s, &type, &valuecharptr, &valuelen )) < 0 ) {
LDAPDebug( LDAP_DEBUG_TRACE,
- "<= slapi_str2entry NULL (parse_line)\n", 0, 0, 0 );
+ "<= str2entry_dupcheck NULL (parse_line)\n", 0, 0, 0 );
continue;
}
#if defined(USE_OPENLDAP)
@@ -662,11 +688,20 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
csnset_free(&valuecsnset);
}
+ if ( dn ) {
+ if ( NULL == slapi_entry_get_dn_const(e) ) {
+ slapi_entry_set_dn( e, slapi_ch_strdup( dn ));
+ }
+ if ( NULL == slapi_entry_get_rdn_const(e) ) {
+ slapi_entry_set_rdn( e, (char *)dn );
+ }
+ }
if ( strcasecmp( type, "dn" ) == 0 ) {
if ( slapi_entry_get_dn_const(e)!=NULL ) {
char ebuf[ BUFSIZ ];
- LDAPDebug( LDAP_DEBUG_ANY,
- "slapi_str2entry: entry has multiple dns \"%s\" and \"%s\" (second ignored)\n",
+ LDAPDebug( LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: entry has multiple dns \"%s\" "
+ "and \"%s\" (second ignored)\n",
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 */
@@ -681,11 +716,21 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
continue;
}
+ if ( strcasecmp( type, "rdn" ) == 0 ) {
+ if ( NULL == slapi_entry_get_rdn_const( e )) {
+ slapi_entry_set_rdn( e, valuecharptr );
+ }
+ /* the memory below was not allocated by the slapi_ch_ functions */
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ continue;
+ }
+
/* retrieve uniqueid */
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "slapi_str2entry: entry has multiple "
+ LDAPDebug (LDAP_DEBUG_ANY, "str2entry_dupcheck: entry has multiple "
"uniqueids %s and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
@@ -787,7 +832,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( slapi_attr_type2plugin( type,(void **)&(attrs[nattrs].sa_pi) ) != 0 )
{
LDAPDebug( LDAP_DEBUG_ANY,
- "<= slapi_str2entry NULL (slapi_attr_type2plugin)\n",
+ "<= str2entry_dupcheck NULL (slapi_attr_type2plugin)\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
if (retmalloc) slapi_ch_free_string(&valuecharptr);
@@ -911,7 +956,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
else
{
/* Failure adding to value tree */
- LDAPDebug( LDAP_DEBUG_ANY, "slapi_str2entry: unexpected failure %d constructing value tree\n", rc, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: unexpected failure %d constructing value tree\n", rc, 0, 0 );
slapi_entry_free( e ); e = NULL;
goto free_and_return;
}
@@ -924,7 +969,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( slapi_entry_get_dn_const(e)==NULL )
{
if (!(SLAPI_STR2ENTRY_INCLUDE_VERSION_STR & flags))
- LDAPDebug( LDAP_DEBUG_ANY, "slapi_str2entry: entry has no dn\n",
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: entry has no dn\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
goto free_and_return;
@@ -945,11 +990,11 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( sa->sa_numdups > 0 )
{
if ( sa->sa_numdups > 1 ) {
- LDAPDebug( LDAP_DEBUG_ANY, "%d duplicate values for attribute "
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: %d duplicate values for attribute "
"type %s detected in entry %s. Extra values ignored.\n",
sa->sa_numdups, sa->sa_type, slapi_entry_get_dn_const(e) );
} else {
- LDAPDebug( LDAP_DEBUG_ANY, "Duplicate value for attribute "
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: Duplicate value for attribute "
"type %s detected in entry %s. Extra value ignored.\n",
sa->sa_type, slapi_entry_get_dn_const(e), 0 );
}
@@ -1014,7 +1059,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( flags & SLAPI_STR2ENTRY_ADDRDNVALS ) {
if ( slapi_entry_add_rdn_values( e ) != LDAP_SUCCESS ) {
LDAPDebug( LDAP_DEBUG_TRACE,
- "slapi_str2entry: entry has badly formatted dn\n",
+ "str2entry_dupcheck: entry has badly formatted dn\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
goto free_and_return;
@@ -1094,11 +1139,72 @@ slapi_str2entry( char *s, int flags )
if ( 0 != ( flags & SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF ) ||
0 != ( flags & ~SLAPI_STRENTRY_FLAGS_HANDLED_BY_STR2ENTRY_FAST ))
{
- e= str2entry_dupcheck( s, flags, read_stateinfo );
+ e= str2entry_dupcheck( NULL/*dn*/, s, flags, read_stateinfo );
+ }
+ else
+ {
+ e= str2entry_fast( NULL/*dn*/, s, flags, read_stateinfo );
+ }
+ if (!e)
+ return e; /* e == NULL */
+
+ if ( flags & SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES )
+ {
+ if ( flags & SLAPI_STR2ENTRY_NO_SCHEMA_LOCK )
+ {
+ schema_expand_objectclasses_nolock( e );
+ }
+ else
+ {
+ slapi_schema_expand_objectclasses( e );
+ }
+ }
+
+ if ( flags & SLAPI_STR2ENTRY_TOMBSTONE_CHECK )
+ {
+ /*
+ * Check if the entry is a tombstone.
+ */
+ if(slapi_entry_attr_hasvalue(e, SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_VALUE_TOMBSTONE))
+ {
+ e->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE;
+ }
+ }
+ return e;
+}
+
+/*
+ * string s does not include dn.
+ */
+Slapi_Entry *
+slapi_str2entry_ext( const char *dn, char *s, int flags )
+{
+ Slapi_Entry *e;
+ int read_stateinfo= ~( flags & SLAPI_STR2ENTRY_IGNORE_STATE );
+
+ if (NULL == dn)
+ {
+ return slapi_str2entry( s, flags );
+ }
+
+ LDAPDebug( LDAP_DEBUG_ARGS,
+ "slapi_str2entry_ext: flags=0x%x, dn=\"%s\", entry=\"%.50s...\"\n",
+ flags, dn, s );
+
+
+ /*
+ * If well-formed LDIF has not been provided OR if a flag that is
+ * not handled by str2entry_fast() has been passed in, call the
+ * slower but more forgiving str2entry_dupcheck() function.
+ */
+ if ( 0 != ( flags & SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF ) ||
+ 0 != ( flags & ~SLAPI_STRENTRY_FLAGS_HANDLED_BY_STR2ENTRY_FAST ))
+ {
+ e= str2entry_dupcheck( dn, s, flags, read_stateinfo );
}
else
{
- e= str2entry_fast( s, flags, read_stateinfo );
+ e= str2entry_fast( dn, s, flags, read_stateinfo );
}
if (!e)
return e; /* e == NULL */
@@ -1412,28 +1518,142 @@ entry2str_internal( Slapi_Entry *e, int *len, int entry2str_ctrl )
return ebuf;
}
+static char *
+entry2str_internal_ext( Slapi_Entry *e, int *len, int entry2str_ctrl)
+{
+ if (entry2str_ctrl & SLAPI_DUMP_RDN_ENTRY) /* dump rdn: ... */
+ {
+ char *ebuf;
+ char *ecur;
+ size_t elen = 0;
+ size_t typebuf_len = 64;
+ char *typebuf = (char *)slapi_ch_malloc(typebuf_len);
+ Slapi_Value rdnvalue;
+ /*
+ * In string format, an entry looks like this:
+ * rdn: <normalized rdn>\n
+ * [<attr>: <value>\n]*
+ */
+
+ ecur = ebuf = NULL;
+
+ value_init(&rdnvalue, NULL, CSN_TYPE_NONE, NULL);
+
+ /* find length of buffer needed to hold this entry */
+ if (NULL == slapi_entry_get_rdn_const(e) &&
+ NULL != slapi_entry_get_dn_const(e))
+ {
+ /* e_srdn is not filled in, use e_sdn */
+ slapi_rdn_init_all_sdn(&e->e_srdn, slapi_entry_get_sdn_const(e));
+ }
+ if (NULL != slapi_entry_get_rdn_const(e))
+ {
+ slapi_value_set_string(&rdnvalue, slapi_entry_get_rdn_const(e));
+ elen += entry2str_internal_size_value("rdn", &rdnvalue,
+ entry2str_ctrl,
+ ATTRIBUTE_PRESENT,
+ VALUE_PRESENT);
+ }
+
+ /* Count the space required for the present attributes */
+ elen += entry2str_internal_size_attrlist(e->e_attrs, entry2str_ctrl,
+ ATTRIBUTE_PRESENT);
+
+ /* Count the space required for the deleted attributes */
+ if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
+ {
+ elen += entry2str_internal_size_attrlist(e->e_deleted_attrs,
+ entry2str_ctrl,
+ ATTRIBUTE_DELETED);
+ }
+
+ elen += 1;
+ ecur = ebuf = (char *)slapi_ch_malloc(elen);
+
+ /* put the rdn */
+ if (slapi_entry_get_rdn_const(e) != NULL)
+ {
+ /* put "rdn: <normalized rdn>" */
+ entry2str_internal_put_value("rdn", NULL, CSN_TYPE_NONE,
+ ATTRIBUTE_PRESENT, &rdnvalue,
+ VALUE_PRESENT, &ecur, &typebuf,
+ &typebuf_len, entry2str_ctrl);
+ }
+
+ /* Put the present attributes */
+ entry2str_internal_put_attrlist(e->e_attrs, ATTRIBUTE_PRESENT,
+ entry2str_ctrl, &ecur,
+ &typebuf, &typebuf_len );
+
+ /* Put the deleted attributes */
+ if(entry2str_ctrl & SLAPI_DUMP_STATEINFO)
+ {
+ entry2str_internal_put_attrlist(e->e_deleted_attrs,
+ ATTRIBUTE_DELETED, entry2str_ctrl,
+ &ecur, &typebuf, &typebuf_len );
+ }
+
+ *ecur = '\0';
+ if ((size_t)(ecur - ebuf + 1) > elen)
+ {
+ /* this should not happen */
+ slapi_log_error (SLAPI_LOG_FATAL, NULL,
+ "entry2str_internal_ext: array boundary wrote: "
+ "bufsize=%ld wrote=%ld\n",
+ elen, (ecur - ebuf + 1));
+ }
+
+ if ( NULL != len ) {
+ *len = ecur - ebuf;
+ }
+
+ slapi_ch_free((void**)&typebuf);
+ value_done(&rdnvalue);
+
+ return ebuf;
+ }
+ else /* dump "dn: ..." */
+ {
+ return entry2str_internal( e, len, entry2str_ctrl );
+ }
+}
+
+/*
+ * This function converts an entry to the entry string starting with "dn: ..."
+ */
char *
slapi_entry2str( Slapi_Entry *e, int *len )
{
return entry2str_internal(e, len, 0);
}
+/*
+ * This function converts an entry to the entry string starting with "dn: ..."
+ */
char *
slapi_entry2str_dump_uniqueid( Slapi_Entry *e, int *len )
{
return entry2str_internal(e, len, SLAPI_DUMP_UNIQUEID);
}
+/*
+ * This function converts an entry to the entry string starting with "dn: ..."
+ */
char *
slapi_entry2str_no_opattrs( Slapi_Entry *e, int *len )
{
return entry2str_internal(e, len, SLAPI_DUMP_NOOPATTRS);
}
+/*
+ * This function converts an entry to the entry string starting with "dn: ..."
+ * by default. If option includes SLAPI_DUMP_RDN_ENTRY bit, it does the entry
+ * to "rdn: ..."
+ */
char *
slapi_entry2str_with_options( Slapi_Entry *e, int *len, int options )
{
- return entry2str_internal(e, len, options);
+ return entry2str_internal_ext(e, len, options);
}
static int entry_type = -1; /* The type number assigned by the Factory for 'Entry' */
@@ -1474,6 +1694,8 @@ slapi_entry_alloc()
{
Slapi_Entry *e= (Slapi_Entry *) slapi_ch_calloc( 1, sizeof(struct slapi_entry) );
slapi_sdn_init(&e->e_sdn);
+ slapi_rdn_init(&e->e_srdn);
+
e->e_extension = factory_create_extension(get_entry_object_type(),e,NULL);
if(!counters_created)
{
@@ -1514,6 +1736,8 @@ slapi_entry_free( Slapi_Entry *e ) /* JCM - Should be ** so that we can NULL the
ENTRY_DUMP(e,"slapi_entry_free");
factory_destroy_extension(get_entry_object_type(),e,NULL/*Parent*/,&(e->e_extension));
slapi_sdn_done(&e->e_sdn);
+ slapi_rdn_done(&e->e_srdn);
+
csnset_free(&e->e_dncsnset);
csn_free(&e->e_maxcsn);
slapi_ch_free((void **)&e->e_uniqueid);
@@ -1574,7 +1798,8 @@ slapi_entry_size(Slapi_Entry *e)
if (e->e_uniqueid) size += strlen(e->e_uniqueid) + 1;
if (e->e_dncsnset) size += csnset_size(e->e_dncsnset);
if (e->e_maxcsn) size += sizeof( CSN );
- size += slapi_dn_size(&e->e_sdn);
+ size += slapi_dn_size(&e->e_sdn); /* covers rdn format,
+ since (rdn length < dn length) */
size += slapi_attrlist_size(e->e_attrs);
if (e->e_deleted_attrs) size += slapi_attrlist_size(e->e_deleted_attrs);
if (e->e_virtual_attrs) size += slapi_attrlist_size(e->e_virtual_attrs);
@@ -1605,6 +1830,7 @@ slapi_entry_dup( const Slapi_Entry *e )
slapi_entry_init(ec,NULL,NULL);
slapi_sdn_copy(slapi_entry_get_sdn_const(e),&ec->e_sdn);
+ slapi_srdn_copy(slapi_entry_get_srdn_const(e),&ec->e_srdn);
/* duplicate the dncsn also */
ec->e_dncsnset= csnset_dup(e->e_dncsnset);
@@ -1688,12 +1914,37 @@ slapi_entry_get_sdn( Slapi_Entry *e )
return &e->e_sdn;
}
+const Slapi_RDN *
+slapi_entry_get_srdn_const( const Slapi_Entry *e )
+{
+ return &e->e_srdn;
+}
+
+Slapi_RDN *
+slapi_entry_get_srdn( Slapi_Entry *e )
+{
+ return &e->e_srdn;
+}
+
const char *
slapi_entry_get_dn_const( const Slapi_Entry *e )
{
return (slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)));
}
+const char *
+slapi_entry_get_rdn_const( const Slapi_Entry *e )
+{
+ return (slapi_rdn_get_rdn(slapi_entry_get_srdn_const(e)));
+}
+
+/* slapi_rdn_get_nrdn could modify srdn in it. So, it cannot take const. */
+const char *
+slapi_entry_get_nrdn_const( const Slapi_Entry *e )
+{
+ return (slapi_rdn_get_nrdn(slapi_entry_get_srdn((Slapi_Entry *)e)));
+}
+
/*
* WARNING - The DN is passed in *not* copied.
*/
@@ -1703,12 +1954,28 @@ slapi_entry_set_dn( Slapi_Entry *e, char *dn )
slapi_sdn_set_dn_passin(slapi_entry_get_sdn(e),dn);
}
+/*
+ * WARNING - The DN is copied.
+ * The DN could be dn or RDN.
+ */
+void
+slapi_entry_set_rdn( Slapi_Entry *e, char *dn )
+{
+ slapi_rdn_set_all_dn(slapi_entry_get_srdn(e),dn);
+}
+
void
slapi_entry_set_sdn( Slapi_Entry *e, const Slapi_DN *sdn )
{
slapi_sdn_copy(sdn,slapi_entry_get_sdn(e));
}
+void
+slapi_entry_set_srdn( Slapi_Entry *e, const Slapi_RDN *srdn )
+{
+ slapi_srdn_copy(srdn, slapi_entry_get_srdn(e));
+}
+
const char *
slapi_entry_get_uniqueid( const Slapi_Entry *e )
{
@@ -2625,13 +2892,14 @@ int
entry_apply_mods( Slapi_Entry *e, LDAPMod **mods )
{
int err, j;
+ LDAPMod **mp = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> entry_apply_mods\n", 0, 0, 0 );
err = LDAP_SUCCESS;
- for ( j = 0; mods[j] != NULL; j++ )
+ for ( mp = mods; mp && *mp; mp++ )
{
- err= entry_apply_mod( e, mods[j] );
+ err = entry_apply_mod( e, *mp );
if ( err != LDAP_SUCCESS ) {
break;
}