Subject: RE: WG Last Call on URP I-D

From: "Steven Legg" <[email-masked]>
Date: Tue, 4 Sep 2001 18:18:11 +1100

John McMeeking wrote:
> We have reviewed the LDUP Update Resolution Procedures Internet Draft
> (draft-ietf-ldup-urp-04.txt) and have the following comments.

Thanks for taking the time to have a close look at the document.

>
>
> 1.  Section 4.4, second para.  It seems that a glue entry ought to be used
> when breaking DIT loops.  The glue entry would contain the DN of the
> entry's parent at the time it was moved to Lost & Found.  Without this,
> there is nothing to tell an administrator where this entry originally came
> from.  We also note that glue entries are ill-defined at best in many
> documents, and it is not clear whether statements that "a glue entry has
> knowledge only of its name" is meant to imply that is knows the DN of the
> entry it represents, or that a glue entry has its RDN (entryuuid=x) as its
> only attribute.

The description of glue entries in the architecture draft is inaccurate
and needs further work. The URP draft is written on the assumption that
certain concepts, like glue entries, replication agreements, Update Vectors,
etc, are properly specified in the architecture draft. Insofar as they are
not properly described, that is a problem with the architecture draft, not
the URP draft.

Glue entries touch upon the area of Directory Specific Entries, manageDSAIT
controls and like, which have much wider scope than just URP and are still
under debate. These topics are something the working group will have to
address before LDUP can be considered complete but right now the URP
document
isn't the place to be resolving them.

In the meantime, like so many things in LDAP, one must look to X.500
for a complete explanation.

FYI, as far as URP is concerned, a glue entry can contain anything that
a regular entry can contain except that it isn't necessarily a complete
entry (parts can be missing) and isn't normally seen by average users.

>
>
> 2.  Section 5.1.3, b and c.  You might note that Section 5.2 will show why
> attribute value deletion records are not required in these cases.

Case c) explicitly *does* require (attribute) value deletion records.
An attribute deletion record instead of value deletion records for case b)
was a free design choice (based on what is most likely to match the user's
intention) so I don't see in what way Section 5.2 shows why value deletion
records are not required for case b). Section 5.2 would work either way.

> Under
> (d), you might note that d) covers the special case for replace where a
> replace with no attribute values is treated as a attribute deletion.

I'll add an "if any" to the end of the last sentence in d).
I'd rather not say that a replace with no values is treated like a
deletion since a replace with listed values is most definitely *not*
treated like a deletion with listed values. I think it is better to
describe each case in isolation.

>
>
> 3.  Section 5.2, 1st para.  Clarify that supplier is scanning entry,
> attribute, and value CSNs.  Current wording could leave one to think the
> supplier is just looking at entry CSNs.

The first paragraph introduces the basic idea and the subsequent paragraphs
provide the detail. It should be abundantly clear from the subsequent
paragraphs that the Name CSN, Parent CSN, Entry CSN and attribute value CSNs
of an entry are all examined.

Anyway, I propose this rewording of the third sentence in the first
paragraph.

  "Conceptually, the supplier scans all the entries (glue and non-glue),
   entry contents and deletion records that are covered by the replication
   agreement with the consumer" ...

> In the second paragraph, "A
> p-add-entry primitive is generated for each entry whose entry CSN is
> greater than the Update Vector CSN for the same replica."  what does "same
> replica" refer to?  Consumer replica?

Would adding this following paragraph after the first paragraph clarify
the situation ?

  "The consumer's Update Vector has a CSN for each replica in the replica
   group. Each CSN held by the supplier contains a Replica Identifier.
   When a CSN held by the supplier is compared to the consumer's Update
   Vector during the generation of replication primitives it is compared
   to the single CSN in the consumer's Update Vector that has the same
   Replica Identifier as the held CSN."

If so, I will also tweak the wording of the subsequent paragraphs, e.g.

  "A p-add-entry primitive is generated for each entry whose Entry CSN
   is greater than the Update Vector CSN with the same Replica Identifier."

>
> 4.  Section 5.3.5, 2nd para.  Could improve the grammar of the 3rd sentnce
> by changing "If not, it disambiguates the names of the entries by adding
> the Unique Identifier (i.e. the entryUUID attribute) of each of the
> conflicting entries to their own RDN" to "... to each entry's RDN."

That wording might suggest that every UUID is added to every conflicting
entry. How about this wording instead ?

  "If not, it disambiguates the names of the entries
   by adding each conflicting entry's Unique Identifier to its RDN
   (i.e. making the value of its entryUUID attribute distinguished)."

>
>
> 5. Section 5.3.5, CheckUniqueness function:
>
>       IF E.rdn is empty
>          make C.uid distinguished
>
>    Please explain this test.  Why are we checking to see if the entry has
> no RDN, and IF so, make the OLD conflicting entry's name contain the UID?

It's a typo.

> Perhaps make C.uid distinguished should be make E.uid distinguished?

Yes. I'll make the correction.

>
>
> 6.  Section 5.3.5, just before RenameEntry(E,P).  The pareter description
> is missing the name of the second parameter.  Perhaps:
> "The parameters to this procedure are the entry, E, and the p-add-entry or
> p-rename-entry primitive, P, specifying the new RDN."
> ", P," was missing.

OR
  "The parameters to this procedure are the entry, E, and P, the p-add-entry
   or p-rename-entry primitive specifying the new RDN."

>
>
> 7.  Section 5.3.5, RenameEntry(E,P).  After
>             V.csn := GenerateNextCSN(V.csn)
> Should a log-based implementation log a primitive for this change?  We
> think so.

Yes it should. This action is mandated in the first paragraph of
Section 5.3.3.

>
> The above comment also applies to 5.3.7 and 5.3.8.

And to Section 5.3.11. All these cases are covered by the first paragraph
of Section 5.3.3.

>
>
> 8.  Section 5.3.6.
>                     replace V with P.value if they are not identical
> Shouldn't this be:
>                     replace V with P.value if they are not identical AND
> the type is single-valued?

No. The action also applies to values of multi-valued attribute types
for the reason given in the first paragraph of Section 5.3.4.

>
> 9.  Section 5.3.8
>
>                FOREACH attribute value, V, of type P.type in E (if any)
>                   IF P.csn > V.csn
>                      IF V is distinguished
>                         IF ProtectDistinguished()
>                            V.csn := GenerateNextCSN(P.csn)
>                         ELSE
>                            {
>                            R := E.rdn
>                            remove value V
>                            CheckUniqueness(E, E.superior, R)
>                            }
>                      ELSE
>                         remove value V
> >>>            StoreAttributeDeletion (P.uid, P.type, P.csn)
>
> If ProtectDistinguished() is TRUE, then the attribute deletion is false.
> We should store Attribute Value deletions for all NON-distinguished values
> - or, store an Attribute deletion and an attribute ADD for the
> distinguished value.

The procedure is already doing the latter. The CSN on the distinguished
value is reset to the value returned by the GenerateNextCSN function call
so a p-add-attribute-value primitive will be generated in due course.

>
>
> 10. Section 5.3.11 and 5.3.12.  Where we create glue entries, i.e.
>            E := CreateGlueEntry(P.uid)
> Shouldn't this be followed by:
>            E.superior = LOST_AND_FOUND

The CreateGlueEntry function does this already. To quote from Section 5.3.2:
"The CreateGlueEntry function is called when required to create a glue
entry as a subordinate of Lost & Found".

>
>
> 11.  Section 5.3.12
>                      replace V with N.value if they are not identical
> Shouldn't this be:
>                      replace V with N.value if they are not identical AND
> the type is single-valued?

Same response as for point 8.

>
>
> 12.  Section 5.3.11.  We have two additional concerns with the
p-move-entry
> primitive.  As written, it appears that Lost and Found of the
participating
> replicas do not all end up in the same state.

They all end up in the same state when the full implications of the
GenerateNextCSN function are considered. The missing steps in the example
are discussed below.

> Also, by moving entries
> directly under Lost & Found, information about the original parent of the
> entry is lost.  We suggest that p-move-entry place entries under a glue
> entry that has knowledge of the original parent DN.

There is no doubt all sorts of useful information about the recent states
of an entry that we could be collecting to present to administrators later,
but since it doesn't have any bearing on URP and LDUP server interworking
I've chosen not to go down that rat hole. URP doesn't preclude
implementations
from collecting and keeping additional records and I'm happy to leave such
things to experimentation for now.

>
> The following example illustrates the first concern:
>
> Consider the following DIT:
>
>            o=A            L & F
>             |
>        ------------
>        |          |
>       ou=B       ou=C
>
> And suppose there are two replicas, 1 & 2.
>
> at t1:  client on server 1 moves ou=C beneath ou=B
>
> at t2:  client on server 2 moves ou=B beneath ou=C
>
> DITs on each server now look like:
>
> Server 1:                 Server 2:
>            o=A                       o=A
>             |                         |
>        ------------              ------------
>        |          |              |           |
>       ou=B                                 ou=C
>        |                                     |
>       ou=C                                 ou=B
>
> at t3:  server 1 receives updates from server 2
>    p-move-entry(B, t2, C)
> This results in a loop, and the resolution is to move B to L&F

In addition, the GenerateNextCSN function is called to reset the CSN
on B's superior reference. This means that immediately (log-based) or
eventually (state-based) a p-move-entry(B, t3, LOST_AND_FOUND)
is generated and propagated to server 2.

>
> at t4:  server 2 receives updates from server 1
>    p-move-entry(C, t1, B)
> This results in a loop, and the resolution is to move C to L&F

Likewise, a p-move-entry(C, t4, LOST_AND_FOUND) is generated and
propagated to server 1.

>
> Final outcome:
>
> Server 1:                        Server 2:
>   o=A            L & F               o=A            L & F
>    |               |                  |               |
>                glue entry                        glue entry
>                    |                                  |
>                  ou=B                               ou=C
>                    |                                  |
>                  ou=C                               ou=B
>
> We ended up with differing outcomes in Lost and Found.

Taking into consideration the two extra p-move-entry primitives,
the final outcome at both servers is:

          o=A            L & F
           |               |
                      ------------
                      |          |
                     ou=B       ou=C

Note that in this case there are no glue entries created.

Regards,
Steven

---

From: "John McMeeking" <[email-masked]>
Date: Wed, 5 Sep 2001 10:00:46 -0500

My two bits worth...

RFC2596 seems to leave a bit of room for interpretation.  As I read it (in
the context of this discussion), section 3.7 seems to refer to deleting
specific values.  I don't think it applies to deleting all values of an
attribute.  I would expect that a modify that deletes a specific value
requires a match on the attribute options.  Deleting or replacing the
entire attribute would not require a match.  "Replacing" a single value, is
a delete-value and add-value

So, for an entry like:

dn: cn=some entry
...
description: description of entry
description;lang-en: english description of entry

1) Delete entire attribute

dn: cn=some entry
changetype: modify
delete: description

would delete all description values, including description;lang-en

2)  delete specific value, but didn't match option

dn: cn=some entry
changetype: modify
delete: description
description: english description of entry

would fail

3) Replace entire attribute

dn: cn=some entry
changetype: modify
replace: description
description: new description

would result in

dn: cn=some entry
...
description: new description
# description;lang-en: english description of entry -- this value deleted

4) Replace specific value, but didn't match option

dn: cn=some entry
changetype: modify
replace: description
description: english description of entry
-
add: description;lang-en new english description

would fail

John  McMeeking
OS/400 Directory Services
(507)253-4596 (T/L) 553-4596

                    [email-masked]                                                                         
                    m (Richard V             To:     [email-masked], [email-masked]       
                    Huber)                   cc:     [email-masked]                                         
                    Sent by:                 Subject:     Re: WG Last Call on URP I-D                          
                    owner-ietf-ldup@ma                                                                         
                    il.imc.org                                                                                 

                    09/05/2001 09:05                                                                           
                    AM                                                                                         

I include an extract from an exchange between Ryan and Steven.  Ryan
notes that he would expect a delete of an attribute type to include all
subtypes as well.  I would have thought the same, but a check of
RFC2596 (Language Tags) shows:

   3.7. Modify Operation

   A client MAY provide a language code in an AttributeDescription as
   part of a modification element in the modify operation.

   Attribute types and language codes MUST match exactly against values
   stored in the directory.  For example, if the modification is a
   "delete", then if the stored values to be deleted have a language
   code, the language code MUST be provided in the modify operation, and
   if the stored values to be deleted do not have a language code, then
   no language code is to be provided.

In other operations (e.g. compare, search results), giving the
attribute type DOES include all subtypes, but not for delete.

So if we are going to be consistent with other work on attribute
options (and 2596 seems to be the only RFC that discusses them in
detail), we should assume that a request to delete cn DOES NOT delete
cn;foobar.

Rick Huber

: On Wed, Sep 05, 2001 at 07:34:41PM +1100, Steven Legg wrote:
: |
: | Ryan,
: |
: | Ryan Moats wrote:
: | > What I seemed to miss was the discussion of primitive generation
: | > with respect to attribute types, attribute subtypes and
: | > attribute options.
: | > Specifically there was no clarification
: | >
: | > - whether attribute subtypes and options were or were not
: | > supported.  I
: | >   believe absense of a restriction means they are, but others
: | > could read
: | >   absense of a restriction to mean they are not.
: |
: | The absence of any clear direction in URP on subtyping issues is an
: | oversight. I had been assuming that attribute subtyping is basically
: | ignored by URP, as is the case for updating in general and for X.500
: | replication updates in particular. I shall add words to the URP
: | document to the effect that attribute types in a subtype hierarchy
: | are treated as distinct and unrelated types by URP.
: |
: | Attribute options are a different matter since RFC 2251 isn't clear
: | about how this form of subtyping applies to updates. For example,
: | does a request to delete the cn attribute also delete the cn;foobar
: | attribute ? If I can assume that the answer is no then I can just
: | say that attribute types with options are also treated as distinct
: | and unrelated types by URP. The alternative answer will require more
: | extensive changes.
:
: Hmm, I would think that principle of least surprise would say that
: deleting cn wouls also delete cn;foobar.  I'd like to hear what
: others think of course.

---

From: "John McMeeking" <[email-masked]>
Date: Mon, 10 Sep 2001 07:18:27 -0500

We think both changes would help.  Thanks.

John  McMeeking

                    "Steven Legg"                                                                             
                    <steven.legg@adac       To:     John McMeeking/Rochester/IBM@IBMUS                        
                    el.com.au>              cc:     <[email-masked]>                                       
                                            Subject:     RE: WG Last Call on URP I-D                          
                    09/10/2001 01:46                                                                          
                    AM                                                                                        
                    Please respond to                                                                         
                    steven.legg                                                                               

John,

John McMeeking wrote:
> See
> <JAM>
> responses
> </JAM>

> John McMeeking wrote:
> > 2.  Section 5.1.3, b and c.  You might note that Section
> 5.2 will show
> why
> <JAM>
> I think I let a typo slip through -- I meant b and d (not c).
> Back to the
> original comment: Should there be any statement added that 5.2
> (specifically when p-remove-attribute supercedes other
> primitives) shows
> why value deletion records are not required?
> </JAM>

Now I understand. A statement like the following ?

  "It is not necessary to generate p-remove-attribute-value primitives
   for each of the values actually removed because the p-remove-attribute
   primitive would supersede all such primitives, by the rules in
   Section 5.2."

I'll add it if you think it helps.

> <JAM>
> I think it would be clearer to add a sentence like: "The replace
> alternative with no attribute values generates only an
> attribute deletion
> record."
> </JAM>

Okay. I'll add this.

Regards,
Steven