|
@@ -515,6 +515,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
struct berval *subrdn_avs = NULL;
|
|
struct berval *subrdn_avs = NULL;
|
|
|
struct berval subinitial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
|
|
struct berval subinitial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
|
|
|
int chkblank = 0;
|
|
int chkblank = 0;
|
|
|
|
|
+ int is_dn_syntax = 0;
|
|
|
|
|
|
|
|
if (NULL == dest) {
|
|
if (NULL == dest) {
|
|
|
goto bail;
|
|
goto bail;
|
|
@@ -562,12 +563,63 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
case INTYPE: /* in type; cn=... */
|
|
case INTYPE: /* in type; cn=... */
|
|
|
/* ^ */
|
|
/* ^ */
|
|
|
if (ISEQUAL(*s)) {
|
|
if (ISEQUAL(*s)) {
|
|
|
|
|
+ /* See if the type is defined to use
|
|
|
|
|
+ * the Distinguished Name syntax. */
|
|
|
|
|
+ char savechar;
|
|
|
|
|
+ Slapi_Attr test_attr;
|
|
|
|
|
+
|
|
|
|
|
+ /* We need typestart to be a string containing only
|
|
|
|
|
+ * the type. We terminate the type and then reset
|
|
|
|
|
+ * the string after we check the syntax. */
|
|
|
|
|
+ savechar = *d;
|
|
|
|
|
+ *d = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ slapi_attr_init(&test_attr, typestart);
|
|
|
|
|
+ is_dn_syntax = slapi_attr_is_dn_syntax_attr(&test_attr);
|
|
|
|
|
+
|
|
|
|
|
+ /* Reset the character we modified. */
|
|
|
|
|
+ *d = savechar;
|
|
|
|
|
+
|
|
|
state = B4VALUE;
|
|
state = B4VALUE;
|
|
|
*d++ = *s++;
|
|
*d++ = *s++;
|
|
|
} else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
|
|
} else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
|
|
|
|
|
+ /* See if the type is defined to use
|
|
|
|
|
+ * the Distinguished Name syntax. */
|
|
|
|
|
+ char savechar;
|
|
|
|
|
+ Slapi_Attr test_attr;
|
|
|
|
|
+
|
|
|
|
|
+ /* We need typestart to be a string containing only
|
|
|
|
|
+ * the type. We terminate the type and then reset
|
|
|
|
|
+ * the string after we check the syntax. */
|
|
|
|
|
+ savechar = *d;
|
|
|
|
|
+ *d = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ slapi_attr_init(&test_attr, typestart);
|
|
|
|
|
+ is_dn_syntax = slapi_attr_is_dn_syntax_attr(&test_attr);
|
|
|
|
|
+
|
|
|
|
|
+ /* Reset the character we modified. */
|
|
|
|
|
+ *d = savechar;
|
|
|
|
|
+
|
|
|
state = INVALUE; /* skip a trailing space */
|
|
state = INVALUE; /* skip a trailing space */
|
|
|
*d++ = *s++;
|
|
*d++ = *s++;
|
|
|
} else if (ISSPACE(*s)) {
|
|
} else if (ISSPACE(*s)) {
|
|
|
|
|
+ /* See if the type is defined to use
|
|
|
|
|
+ * the Distinguished Name syntax. */
|
|
|
|
|
+ char savechar;
|
|
|
|
|
+ Slapi_Attr test_attr;
|
|
|
|
|
+
|
|
|
|
|
+ /* We need typestart to be a string containing only
|
|
|
|
|
+ * the type. We terminate the type and then reset
|
|
|
|
|
+ * the string after we check the syntax. */
|
|
|
|
|
+ savechar = *d;
|
|
|
|
|
+ *d = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ slapi_attr_init(&test_attr, typestart);
|
|
|
|
|
+ is_dn_syntax = slapi_attr_is_dn_syntax_attr(&test_attr);
|
|
|
|
|
+
|
|
|
|
|
+ /* Reset the character we modified. */
|
|
|
|
|
+ *d = savechar;
|
|
|
|
|
+
|
|
|
state = B4EQUAL; /* skip a trailing space */
|
|
state = B4EQUAL; /* skip a trailing space */
|
|
|
} else if (ISQUOTE(*s) || SEPARATOR(*s)) {
|
|
} else if (ISQUOTE(*s) || SEPARATOR(*s)) {
|
|
|
/* type includes quote / separator; not a valid dn */
|
|
/* type includes quote / separator; not a valid dn */
|
|
@@ -615,7 +667,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
rc = -1;
|
|
rc = -1;
|
|
|
goto bail;
|
|
goto bail;
|
|
|
} /* otherwise, go through */
|
|
} /* otherwise, go through */
|
|
|
- if (ISESCAPE(*s)) {
|
|
|
|
|
|
|
+ if (!is_dn_syntax || ISESCAPE(*s)) {
|
|
|
subtypestart = NULL; /* if escaped, can't be multivalued dn */
|
|
subtypestart = NULL; /* if escaped, can't be multivalued dn */
|
|
|
} else {
|
|
} else {
|
|
|
subtypestart = d; /* prepare for '+' in the nested DN, if any */
|
|
subtypestart = d; /* prepare for '+' in the nested DN, if any */
|
|
@@ -636,12 +688,12 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
rc = -1;
|
|
rc = -1;
|
|
|
goto bail;
|
|
goto bail;
|
|
|
} else {
|
|
} else {
|
|
|
- if (ISEQUAL(*(s+1))) {
|
|
|
|
|
|
|
+ if (ISEQUAL(*(s+1)) && is_dn_syntax) {
|
|
|
while (ISSPACE(*(d-1))) {
|
|
while (ISSPACE(*(d-1))) {
|
|
|
/* remove trailing spaces */
|
|
/* remove trailing spaces */
|
|
|
d--;
|
|
d--;
|
|
|
}
|
|
}
|
|
|
- } else if (SEPARATOR(*(s+1))) {
|
|
|
|
|
|
|
+ } else if (SEPARATOR(*(s+1)) && is_dn_syntax) {
|
|
|
/* separator is a subset of needsescape */
|
|
/* separator is a subset of needsescape */
|
|
|
while (ISSPACE(*(d-1))) {
|
|
while (ISSPACE(*(d-1))) {
|
|
|
/* remove trailing spaces */
|
|
/* remove trailing spaces */
|
|
@@ -691,7 +743,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
*d++ = *s++; /* '\\' */
|
|
*d++ = *s++; /* '\\' */
|
|
|
PR_snprintf(d, 3, "%X", *s); /* hexpair */
|
|
PR_snprintf(d, 3, "%X", *s); /* hexpair */
|
|
|
d += 2;
|
|
d += 2;
|
|
|
- if (ISPLUS(*s)) {
|
|
|
|
|
|
|
+ if (ISPLUS(*s) && is_dn_syntax) {
|
|
|
/* next type start of multi values */
|
|
/* next type start of multi values */
|
|
|
/* should not be a escape char AND should be
|
|
/* should not be a escape char AND should be
|
|
|
* followed by \\= or \\3D */
|
|
* followed by \\= or \\3D */
|
|
@@ -702,7 +754,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
subtypestart = NULL;
|
|
subtypestart = NULL;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (SEPARATOR(*s) || ISEQUAL(*s)) {
|
|
|
|
|
|
|
+ if ((SEPARATOR(*s) || ISEQUAL(*s)) && is_dn_syntax) {
|
|
|
while (ISSPACE(*(s+1)))
|
|
while (ISSPACE(*(s+1)))
|
|
|
s++; /* remove leading spaces */
|
|
s++; /* remove leading spaces */
|
|
|
s++;
|
|
s++;
|
|
@@ -717,12 +769,12 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
(ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) {
|
|
(ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) {
|
|
|
/* e.g., cn=abc\20 ,... */
|
|
/* e.g., cn=abc\20 ,... */
|
|
|
/* ^ */
|
|
/* ^ */
|
|
|
- if (ISEQUALSTR(s+1)) {
|
|
|
|
|
|
|
+ if (ISEQUALSTR(s+1) && is_dn_syntax) {
|
|
|
while (ISSPACE(*(d-1))) {
|
|
while (ISSPACE(*(d-1))) {
|
|
|
/* remove trailing spaces */
|
|
/* remove trailing spaces */
|
|
|
d--;
|
|
d--;
|
|
|
}
|
|
}
|
|
|
- } else if (SEPARATORSTR(s+1)) {
|
|
|
|
|
|
|
+ } else if (SEPARATORSTR(s+1) && is_dn_syntax) {
|
|
|
/* separator is a subset of needsescape */
|
|
/* separator is a subset of needsescape */
|
|
|
while (ISSPACE(*(d-1))) {
|
|
while (ISSPACE(*(d-1))) {
|
|
|
/* remove trailing spaces */
|
|
/* remove trailing spaces */
|
|
@@ -766,7 +818,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
*d++ = *s++; /* '\\' */
|
|
*d++ = *s++; /* '\\' */
|
|
|
*d++ = *s++; /* HEX */
|
|
*d++ = *s++; /* HEX */
|
|
|
*d++ = *s++; /* HEX */
|
|
*d++ = *s++; /* HEX */
|
|
|
- if (ISPLUSSTR(s-2)) {
|
|
|
|
|
|
|
+ if (ISPLUSSTR(s-2) && is_dn_syntax) {
|
|
|
/* next type start of multi values */
|
|
/* next type start of multi values */
|
|
|
/* should not be a escape char AND should be followed
|
|
/* should not be a escape char AND should be followed
|
|
|
* by \\= or \\3D */
|
|
* by \\= or \\3D */
|
|
@@ -777,9 +829,10 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
subtypestart = NULL;
|
|
subtypestart = NULL;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) {
|
|
|
|
|
- while (ISSPACE(*s)) /* remove leading spaces */
|
|
|
|
|
|
|
+ if ((SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) && is_dn_syntax) {
|
|
|
|
|
+ while (ISSPACE(*s)) {/* remove leading spaces */
|
|
|
s++;
|
|
s++;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
} else if (s + 2 < ends &&
|
|
} else if (s + 2 < ends &&
|
|
|
isxdigit(*(s+1)) && isxdigit(*(s+2))) {
|
|
isxdigit(*(s+1)) && isxdigit(*(s+2))) {
|
|
@@ -836,26 +889,36 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
s++;
|
|
s++;
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- subtypestart = d; /* prepare for '+' in the quoted value, if any */
|
|
|
|
|
|
|
+ if (is_dn_syntax) {
|
|
|
|
|
+ subtypestart = d; /* prepare for '+' in the quoted value, if any */
|
|
|
|
|
+ }
|
|
|
subrdn_av_count = 0;
|
|
subrdn_av_count = 0;
|
|
|
case INQUOTEDVALUE:
|
|
case INQUOTEDVALUE:
|
|
|
if (ISQUOTE(*s)) {
|
|
if (ISQUOTE(*s)) {
|
|
|
if (ISESCAPE(*(d-1))) { /* the quote is escaped */
|
|
if (ISESCAPE(*(d-1))) { /* the quote is escaped */
|
|
|
PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
|
|
PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
|
|
|
} else { /* end of INQUOTEVALUE */
|
|
} else { /* end of INQUOTEVALUE */
|
|
|
- while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
|
|
|
|
|
|
|
+ if (is_dn_syntax) {
|
|
|
|
|
+ while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
|
|
|
|
|
+ d--;
|
|
|
|
|
+ chkblank = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ /* We have to keep the last ' ' of a value in quotes.
|
|
|
|
|
+ * The same idea as the escaped last space:
|
|
|
|
|
+ * "cn=A,ou=B " */
|
|
|
|
|
+ /* ^ */
|
|
|
|
|
+ if (chkblank && ISBLANK(*d)) {
|
|
|
|
|
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
|
|
|
|
|
+ d += 3;
|
|
|
|
|
+ chkblank = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (ISSPACE(*(d-1))) {
|
|
|
|
|
+ /* Convert last trailing space to hex code */
|
|
|
d--;
|
|
d--;
|
|
|
- chkblank = 1;
|
|
|
|
|
- }
|
|
|
|
|
- /* We have to keep the last ' ' of a value in quotes.
|
|
|
|
|
- * The same idea as the escaped last space:
|
|
|
|
|
- * "cn=A,ou=B " */
|
|
|
|
|
- /* ^ */
|
|
|
|
|
- if (chkblank && ISBLANK(*d)) {
|
|
|
|
|
PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
|
|
PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
|
|
|
d += 3;
|
|
d += 3;
|
|
|
- chkblank = 0;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
state = B4SEPARATOR;
|
|
state = B4SEPARATOR;
|
|
|
s++;
|
|
s++;
|
|
|
}
|
|
}
|
|
@@ -866,11 +929,11 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
rc = -1;
|
|
rc = -1;
|
|
|
goto bail;
|
|
goto bail;
|
|
|
} else {
|
|
} else {
|
|
|
- if (ISEQUAL(*s)) {
|
|
|
|
|
|
|
+ if (ISEQUAL(*s) && is_dn_syntax) {
|
|
|
while (ISSPACE(*(d-1))) { /* remove trailing spaces */
|
|
while (ISSPACE(*(d-1))) { /* remove trailing spaces */
|
|
|
d--;
|
|
d--;
|
|
|
}
|
|
}
|
|
|
- } else if (SEPARATOR(*s)) {
|
|
|
|
|
|
|
+ } else if (SEPARATOR(*s) && is_dn_syntax) {
|
|
|
/* separator is a subset of needsescape */
|
|
/* separator is a subset of needsescape */
|
|
|
while (ISSPACE(*(d-1))) { /* remove trailing spaces */
|
|
while (ISSPACE(*(d-1))) { /* remove trailing spaces */
|
|
|
d--;
|
|
d--;
|
|
@@ -917,10 +980,10 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
|
|
|
*d++ = '\\';
|
|
*d++ = '\\';
|
|
|
PR_snprintf(d, 3, "%X", *s); /* hexpair */
|
|
PR_snprintf(d, 3, "%X", *s); /* hexpair */
|
|
|
d += 2;
|
|
d += 2;
|
|
|
- if (ISPLUS(*s++)) {
|
|
|
|
|
|
|
+ if (ISPLUS(*s++) && is_dn_syntax) {
|
|
|
subtypestart = d; /* next type start of multi values */
|
|
subtypestart = d; /* next type start of multi values */
|
|
|
}
|
|
}
|
|
|
- if (SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) {
|
|
|
|
|
|
|
+ if ((SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) && is_dn_syntax) {
|
|
|
while (ISSPACE(*s)) /* remove leading spaces */
|
|
while (ISSPACE(*s)) /* remove leading spaces */
|
|
|
s++;
|
|
s++;
|
|
|
}
|
|
}
|