diff options
author | Noriko Hosoi <nhosoi@redhat.com> | 2010-07-22 09:19:02 -0700 |
---|---|---|
committer | Noriko Hosoi <nhosoi@redhat.com> | 2010-07-22 09:19:02 -0700 |
commit | 700d7c1a199db4a690740636b8bd3e612304ce1e (patch) | |
tree | 495ed00a344f9be889e5185e821959e3c35f25cc /ldap/servers/slapd/dn.c | |
parent | 9d638b3fc25fbc57884a511744943499c7102f40 (diff) | |
download | ds-700d7c1a199db4a690740636b8bd3e612304ce1e.tar.gz ds-700d7c1a199db4a690740636b8bd3e612304ce1e.tar.xz ds-700d7c1a199db4a690740636b8bd3e612304ce1e.zip |
616618 - 389 v1.2.5 accepts 2 identical entries with different DN formats
https://bugzilla.redhat.com/show_bug.cgi?id=616618
Change Description:
. renamed 91upgradednformat.pl to 80upgradednformat.pl to run
upgradednformat before 90subtreerename.pl.
. ported following patches applied to Directory_Server_8_2_Branch
to master and 389-ds-base-1.2.6.
612771 - RHDS 8.1/389 v1.2.5 accepts 2 identical entries with
different DN formats
* commit 50bb2ee6676e10cdda704982dfa831efa4011037
Fix Description:
This patch fixes the upgradednformat utility to eliminate the
duplicated DNs found in the upgrading period. Assuming DN:
attr0=value0,attr1=value1,...,attrn=valuen exists in the DB
and another identical DN is found, the second DN is renamed to
nsuniqueid=<uuid>+attr0=value0,attr1=value1,...,attrn=valuen
, where the <uuid> is the unique id assigned to the entry when
the entry is added to the server. The modification is logged
in the error log.
In addition, there was a bug to handle multi-valued RDNs in
slapi_dn_normalize_ext. In case multi-valued RDN appears with
DN value (e.g., nsuniqueid=<uuid>+cn=uid\=<uid>\,o\=<org>,dc=<dc>),
it was not normalized properly. Introduced second rdn_av_stack
(subinitial_rdn_av_stack) for the nested DN value.
See also:
http://directory.fedoraproject.org/wiki/Upgrade_to_New_DN_Format#Another_Upgrade_Scenario
* commit ebaa18adaf201f75c709e078abd8e32605eddb81
Fix Description:
1) In the previous commit 50bb2ee6676e10cdda704982dfa831efa4011037,
there were 3 places to miss replacing rdn_av_count with subrdn_av_count.
2) A variable subtypestart is used to keep the head of nested
multivalued RDNs. For instance,
seeAlso=cn\=<CN>\+l\=<L>\,o\=<O>,dc=examle,dc=com
^ or ^ or ^
There was a bug to set the first position ("cn" in the above example).
In addition, fixed a warning assigning "const char *" to "char *" in
import_foreman (import-threads.c).
* commit 472a2c0f2f21205390ba87c31c498b4419a932ba
Fix Description:
When newly creating an ancestorid index file, instead of
opening the index file with DB_TRUNCATE option, delete
the file then create it.
616135 - Upgrade failure on Solaris :
tar: db/NetscapeRoot/{DBVERSION,*.db4}:
No such file or directory
* commit e6723421e6dc69408edb2a396eb22da361cff206
Fix Description:
.../'{'DBVERSION,*.db4'}' is not a shell syntax. Process DBVERSION
and *.db4 individually.
Diffstat (limited to 'ldap/servers/slapd/dn.c')
-rw-r--r-- | ldap/servers/slapd/dn.c | 133 |
1 files changed, 75 insertions, 58 deletions
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c index bd22f76e..e50ec768 100644 --- a/ldap/servers/slapd/dn.c +++ b/ldap/servers/slapd/dn.c @@ -493,13 +493,19 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) char *d = NULL; /* work pointer for dest */ char *ends = NULL; char *endd = NULL; - char *typestart = NULL; - char *subtypestart = NULL; /* used for the nested DN */ char *lastesc = NULL; + /* rdn avs for the main DN */ + char *typestart = NULL; int rdn_av_count = 0; struct berval *rdn_avs = NULL; struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ]; + /* rdn avs for the nested DN */ + char *subtypestart = NULL; /* used for nested rdn avs */ + int subrdn_av_count = 0; + struct berval *subrdn_avs = NULL; + struct berval subinitial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ]; int chkblank = 0; + int avstat = 0; if (NULL == dest) { goto bail; @@ -596,6 +602,12 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) rc = -1; goto bail; } /* otherwise, go through */ + if (ISESCAPE(*s)) { + subtypestart = NULL; /* if escaped, can't be multivalued dn */ + } else { + subtypestart = d; /* prepare for '+' in the nested DN, if any */ + } + subrdn_av_count = 0; case INVALUE: /* in value; cn=ABC */ /* ^ */ if (ISESCAPE(*s)) { @@ -612,20 +624,6 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) goto bail; } else { if (ISEQUAL(*(s+1))) { - if (NULL == subtypestart) { - /* e.g., cn=a\=b\,c\=d */ - /* ^ */ - *d = '\0'; - subtypestart = strrchr(*dest, '='); - if (subtypestart) { - /* pointing 'a' in the above example */ - subtypestart++; - } - /* else - * No equal for the nested DN looking value. - * Just through it. - */ - } while (ISSPACE(*(d-1))) { /* remove trailing spaces */ d--; @@ -649,16 +647,18 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) * multivalued RDNs. */ if (subtypestart && - (ISPLUS(*(s+1)) || rdn_av_count > 0)) { - add_rdn_av(subtypestart, d, &rdn_av_count, - &rdn_avs, initial_rdn_av_stack); + (ISPLUS(*(s+1)) || subrdn_av_count > 0)) { + add_rdn_av(subtypestart, d, &subrdn_av_count, + &subrdn_avs, subinitial_rdn_av_stack); } if (!ISPLUS(*(s+1))) { /* at end of this RDN */ - if (rdn_av_count > 1) { - sort_rdn_avs( rdn_avs, rdn_av_count, 1 ); + if (subrdn_av_count > 1) { + sort_rdn_avs( subrdn_avs, + subrdn_av_count, 1 ); } - if (rdn_av_count > 0) { - reset_rdn_avs( &rdn_avs, &rdn_av_count ); + if (subrdn_av_count > 0) { + reset_rdn_avs( &subrdn_avs, + &subrdn_av_count ); subtypestart = NULL; } } @@ -667,9 +667,17 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) *d++ = *s++; /* '\\' */ PR_snprintf(d, 3, "%X", *s); /* hexpair */ d += 2; - if (ISPLUS(*s) && PL_strnstr(s, "\\=", ends - s)) { + if (ISPLUS(*s)) { /* next type start of multi values */ - subtypestart = d; + /* should not be a escape char AND should be + * followed by \\= or \\3D */ + if (!ISESCAPE(*s) && + (PL_strnstr(s, "\\=", ends - s) || + PL_strncaserstr(s, "\\3D", ends - s))) { + subtypestart = d; + } else { + subtypestart = NULL; + } } if (SEPARATOR(*s) || ISEQUAL(*s)) { while (ISSPACE(*(s+1))) @@ -681,26 +689,12 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) } } else if (((state == INVALUE1ST) && (s+2 < ends) && LEADNEEDSESCAPESTR(s+1)) || - ((state == INVALUE) && + ((state == INVALUE) && (((s+2 < ends) && NEEDSESCAPESTR(s+1)) || (ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) { /* e.g., cn=abc\20 ,... */ /* ^ */ if (ISEQUALSTR(s+1)) { - if (NULL == subtypestart) { - /* e.g., cn=a\3Db\2Cc\3Dd */ - /* ^ */ - *d = '\0'; - subtypestart = strrchr(*dest, '='); - if (subtypestart) { - /* pointing 'a' in the above example */ - subtypestart++; - } - /* else - * No equal for the nested DN looking value. - * Just through it. - */ - } while (ISSPACE(*(d-1))) { /* remove trailing spaces */ d--; @@ -724,25 +718,33 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) * multivalued RDNs. */ if (subtypestart && - (ISPLUSSTR(s+1) || rdn_av_count > 0)) { - add_rdn_av(subtypestart, d, &rdn_av_count, - &rdn_avs, initial_rdn_av_stack); + (ISPLUSSTR(s+1) || subrdn_av_count > 0)) { + add_rdn_av(subtypestart, d, &subrdn_av_count, + &subrdn_avs, subinitial_rdn_av_stack); } if (!ISPLUSSTR(s+1)) { /* at end of this RDN */ - if (rdn_av_count > 1) { - sort_rdn_avs( rdn_avs, rdn_av_count, 1 ); + if (subrdn_av_count > 1) { + sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 ); } - if (rdn_av_count > 0) { - reset_rdn_avs( &rdn_avs, &rdn_av_count ); + if (subrdn_av_count > 0) { + reset_rdn_avs( &subrdn_avs, &subrdn_av_count ); + subtypestart = NULL; } } } *d++ = *s++; /* '\\' */ *d++ = *s++; /* HEX */ *d++ = *s++; /* HEX */ - if (ISPLUSSTR(s-2) && PL_strnstr(s, "\\=", ends - s)) { + if (ISPLUSSTR(s-2)) { /* next type start of multi values */ - subtypestart = d; + /* should not be a escape char AND should be followed + * by \\= or \\3D */ + if (!ISESCAPE(*s) && (PL_strnstr(s, "\\=", ends - s) || + PL_strncaserstr(s, "\\3D", ends - s))) { + subtypestart = d; + } else { + subtypestart = NULL; + } } if (SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) { while (ISSPACE(*s)) /* remove leading spaces */ @@ -804,6 +806,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) continue; } subtypestart = d; /* prepare for '+' in the quoted value, if any */ + subrdn_av_count = 0; case INQUOTEDVALUE: if (ISQUOTE(*s)) { if (ISESCAPE(*(d-1))) { /* the quote is escaped */ @@ -855,16 +858,17 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) * Track and sort attribute values within * multivalued RDNs. */ - if (ISPLUS(*s) || rdn_av_count > 0) { - add_rdn_av(subtypestart, d, &rdn_av_count, - &rdn_avs, initial_rdn_av_stack); + if (subtypestart && + (ISPLUS(*s) || subrdn_av_count > 0)) { + add_rdn_av(subtypestart, d, &subrdn_av_count, + &subrdn_avs, subinitial_rdn_av_stack); } if (!ISPLUS(*s)) { /* at end of this RDN */ - if (rdn_av_count > 1) { - sort_rdn_avs( rdn_avs, rdn_av_count, 1 ); + if (subrdn_av_count > 1) { + sort_rdn_avs( subrdn_avs, subrdn_av_count, 1 ); } - if (rdn_av_count > 0) { - reset_rdn_avs( &rdn_avs, &rdn_av_count ); + if (subrdn_av_count > 0) { + reset_rdn_avs( &subrdn_avs, &subrdn_av_count ); subtypestart = NULL; } } @@ -897,7 +901,8 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) * Track and sort attribute values within * multivalued RDNs. */ - if (ISPLUS(*s) || rdn_av_count > 0) { + if (typestart && + (ISPLUS(*s) || rdn_av_count > 0)) { add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack); } @@ -907,6 +912,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) } if (rdn_av_count > 0) { reset_rdn_avs( &rdn_avs, &rdn_av_count ); + typestart = NULL; } } @@ -931,7 +937,7 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len) * rdn to our list to sort. We should only be in the INVALUE * or B4SEPARATOR state if we have a valid rdn component to * be added. */ - if ((rdn_av_count > 0) && ((state == INVALUE1ST) || + if (typestart && (rdn_av_count > 0) && ((state == INVALUE1ST) || (state == INVALUE) || (state == B4SEPARATOR))) { add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack); } @@ -1160,6 +1166,17 @@ rdn_av_swap( struct berval *av1, struct berval *av2, int escape ) /* Introduced for the upgrade tool. DON'T USE THIS API! */ char * +slapi_dn_normalize_original( char *dn ) +{ + /* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */ + *(substr_dn_normalize_orig( dn, dn + strlen( dn ))) = '\0'; + /* LDAPDebug( LDAP_DEBUG_TRACE, "<= slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */ + + return( dn ); +} + +/* Introduced for the upgrade tool. DON'T USE THIS API! */ +char * slapi_dn_normalize_case_original( char *dn ) { /* LDAPDebug( LDAP_DEBUG_TRACE, "=> slapi_dn_normalize \"%s\"\n", dn, 0, 0 ); */ |