Author: nkinder
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/replication
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv27689
Modified Files:
windows_protocol_util.c windowsrepl.h
Log Message:
Resolves: 243221
Summary: Trim initials attribute value when sync'ing to AD.
Index: windows_protocol_util.c
===================================================================
RCS file:
/cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windows_protocol_util.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- windows_protocol_util.c 10 Nov 2006 23:45:17 -0000 1.27
+++ windows_protocol_util.c 23 Aug 2007 20:50:56 -0000 1.28
@@ -1315,6 +1315,33 @@
if ( is_straight_mapped_attr(type,is_user,is_nt4) )
{
+ /* The initials attribute is a special case. AD has a constraint
+ * that limits the value length. If we're sending a change
to
+ * the initials attribute to AD, we trim if neccessary.
+ */
+ if (0 == slapi_attr_type_cmp(type, "initials",
SLAPI_TYPE_CMP_SUBTYPE)) {
+ int i = 0;
+ const char *initials_value = NULL;
+ Slapi_Value *value = NULL;
+
+ i = slapi_valueset_first_value(vs,&value);
+ while (i >= 0) {
+ initials_value = slapi_value_get_string(value);
+
+ /* If > AD_INITIALS_LENGTH, trim the value */
+ if (strlen(initials_value) > AD_INITIALS_LENGTH) {
+ char *new_initials = PL_strndup(initials_value, AD_INITIALS_LENGTH);
+ /* the below hands off memory */
+ slapi_value_set_string_passin(value, new_initials);
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: windows_create_remote_entry: "
+ "Trimming initials attribute to %d characters.\n",
+ agmt_get_long_name(prp->agmt), AD_INITIALS_LENGTH);
+ }
+
+ i = slapi_valueset_next_value(vs, i, &value);
+ }
+ }
/* copy over the attr values */
slapi_entry_add_valueset(new_entry,type,vs);
} else
@@ -1461,7 +1488,26 @@
/* Check to see if this attribute is passed through */
if (is_straight_mapped_attr(attr_type,is_user,is_nt4)) {
- /* If so then just copy over the mod */
+ /* The initials attribute is a special case. AD has a constraint
+ * that limits the value length. If we're sending a change to
+ * the initials attribute to AD, we trim if neccessary.
+ */
+ if (0 == slapi_attr_type_cmp(attr_type, "initials", SLAPI_TYPE_CMP_SUBTYPE))
{
+ int i;
+ for (i = 0; mod->mod_bvalues[i] != NULL; i++) {
+ /* If > AD_INITIALS_LENGTH, trim the value */
+ if (mod->mod_bvalues[i]->bv_len > AD_INITIALS_LENGTH) {
+ mod->mod_bvalues[i]->bv_val[AD_INITIALS_LENGTH] = '\0';
+ mod->mod_bvalues[i]->bv_len = AD_INITIALS_LENGTH;
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: windows_map_mods_for_replay: "
+ "Trimming initials attribute to %d characters.\n",
+ agmt_get_long_name(prp->agmt), AD_INITIALS_LENGTH);
+ }
+ }
+ }
+
+ /* copy over the mod */
slapi_mods_add_modbvps(&mapped_smods,mod->mod_op,attr_type,mod->mod_bvalues);
} else
{
@@ -1521,9 +1567,12 @@
LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_map_mods_for_replay\n", 0, 0, 0
);
}
-/* Returns non-zero if the attribute value sets are identical */
-static int
-attr_compare_equal(Slapi_Attr *a, Slapi_Attr *b)
+
+/* Returns non-zero if the attribute value sets are identical. If you want to
+ * compare the entire attribute value, set n to 0. You can compare only the
+ * first n characters of the values by passing in the legth as n. */
+static int
+attr_compare_equal(Slapi_Attr *a, Slapi_Attr *b, int n)
{
/* For now only handle single values */
Slapi_Value *va = NULL;
@@ -1535,23 +1584,25 @@
slapi_attr_get_numvalues(a,&num_a);
slapi_attr_get_numvalues(b,&num_b);
- if (num_a == num_b)
- {
+ if (num_a == num_b) {
slapi_attr_first_value(a, &va);
slapi_attr_first_value(b, &vb);
- if (va->bv.bv_len == vb->bv.bv_len)
- {
- if (0 != memcmp(va->bv.bv_val,vb->bv.bv_val,va->bv.bv_len))
- {
+ /* If either val is less than n, then check if the length, then values are
+ * equal. If both are n or greater, then only compare the first n chars.
+ * If n is 0, then just compare the entire attribute. */
+ if ((va->bv.bv_len < n) || (vb->bv.bv_len < n) || (n == 0)) {
+ if (va->bv.bv_len == vb->bv.bv_len) {
+ if (0 != memcmp(va->bv.bv_val, vb->bv.bv_val, va->bv.bv_len)) {
+ match = 0;
+ }
+ } else {
match = 0;
}
- } else
- {
+ } else if (0 != memcmp(va->bv.bv_val, vb->bv.bv_val, n)) {
match = 0;
}
- } else
- {
+ } else {
match = 0;
}
return match;
@@ -2554,7 +2605,17 @@
{
if (!mapdn)
{
- int values_equal = attr_compare_equal(attr,local_attr);
+ int values_equal = 0;
+
+ /* AD has a legth contraint on the initials attribute,
+ * so treat is as a special case. */
+ if (0 == slapi_attr_type_cmp(type,"initials",SLAPI_TYPE_CMP_SUBTYPE)
&& !to_windows) {
+ values_equal = attr_compare_equal(attr, local_attr, AD_INITIALS_LENGTH);
+ } else {
+ /* Compare the entire attribute values */
+ values_equal = attr_compare_equal(attr, local_attr, 0);
+ }
+
/* If it is then we need to replace the local values with the remote values if they
are different */
if (!values_equal)
{
Index: windowsrepl.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/replication/windowsrepl.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- windowsrepl.h 10 Nov 2006 23:45:17 -0000 1.9
+++ windowsrepl.h 23 Aug 2007 20:50:56 -0000 1.10
@@ -97,4 +97,6 @@
/* Used to work around a schema incompatibility between Microsoft and the IETF */
#define FAKE_STREET_ATTR_NAME "in#place#of#streetaddress"
+/* Used to work around contrained attribute legth for initials on AD */
+#define AD_INITIALS_LENGTH 6