Parse x.500 DN and change order displayed

Discussion in 'Perl Misc' started by SecureIT, Mar 31, 2008.

  1. SecureIT

    SecureIT Guest

    I am trying to change this

    "cn=Bob Smith+serialNumber=CR013120080827,o=ICM,c=US"

    to this:

    "serialNumber=CR013120080827+cn=Bob Smith,o=ICM,c=US"

    There are about 2000 entries like this and I need to have them all
    displayed with serialNumber first, and cn last then the rest of the
    DN, the names and serialNumbers are all unique to each entry.

    Any help would be great

    Thanks,
    gotsecure
     
    SecureIT, Mar 31, 2008
    #1
    1. Advertisements

  2. SecureIT

    Uri Guttman Guest

    S> I am trying to change this
    S> "cn=Bob Smith+serialNumber=CR013120080827,o=ICM,c=US"

    S> to this:

    S> "serialNumber=CR013120080827+cn=Bob Smith,o=ICM,c=US"

    S> There are about 2000 entries like this and I need to have them all
    S> displayed with serialNumber first, and cn last then the rest of the
    S> DN, the names and serialNumbers are all unique to each entry.

    are all the entries separated by +? how many are there (you show only 2)?

    if it is always + then you can just split the lines, grab out the cn one
    (use grep) and also filter out the rest. then order them as you
    want. call join '+' to rebuild the line. it can also be done with a hash
    but that is about the same amount of code.

    uri
     
    Uri Guttman, Mar 31, 2008
    #2
    1. Advertisements

  3. Without escape sequences like "\," and "\+" in the DNs (if that's
    allowed anyway, I don't remember the details of X.500 Dn syntax), this
    moves serialNumber first in each RDN:

    s/(^|,)([^,]*)\+(serialNumber=[^+,]*)(?=[+,])/$1$3+$2/gi;
    die "didn't catch all 'foo+serialNumber's" if /\+serialNumber=/i;
     
    Hallvard B Furuseth, Mar 31, 2008
    #3
  4. SecureIT

    SecureIT Guest

    That worked great, thanks so much. Just ran it and all 2000 DN's are
    properly formatted now.

    -G
     
    SecureIT, Mar 31, 2008
    #4
  5. SecureIT

    szr Guest

    Using this regex will take care of \, and \+ escapes:

    s/(^|(?<!\\),)((?:[^,]|\\,)*)\+(serialNumber=(?:[^+,]|\\[+,])*)(?=(?<!\\)[+,])/$1$3+$2/gi;


    Matches:

    my $dn = "cn=Bob Smith+serialNumber=CR013120080827,o=ICM,c=US";
    $dn =~ s/
    (^|(?<!\\),) ((?:[^,]|\\,)*) \+
    (serialNumber = (?:[^+,] | \\[+,])*)
    (?=(?<!\\)[+,])
    /$1$3+$2/gix;
    print $dn;


    __OUTPUT__
    serialNumber=CR013120080827+cn=Bob Smith,o=ICM,c=US


    And:

    my $dn = "cn=Smith\\, Bob+serialNumber=CR01312\\+0080827,o=ICM,c=US";
    $dn =~ s/
    (^|(?<!\\),) ((?:[^,]|\\,)*) \+
    (serialNumber = (?:[^+,] | \\[+,])*)
    (?=(?<!\\)[+,])
    /$1$3+$2/gix;
    print $dn;


    __OUTPUT__
    serialNumber=CR01312\+0080827+cn=Smith\, Bob,o=ICM,c=US


    Hope this helps.
     
    szr, Mar 31, 2008
    #5
  6. SecureIT

    Uri Guttman Guest

    S> I am trying to change this
    S> "cn=Bob Smith+serialNumber=CR013120080827,o=ICM,c=US"S> There are about 2000 entries like this and I need to have them all
    S> displayed with serialNumber first, and cn last then the rest of the
    S> DN, the names and serialNumbers are all unique to each entry.
    d> Am I missing something? Why can't (or shouldn't) he do this?
    d> $entry =~ s/(cn[^+]+)\+([^,]+)(.*)$/$2+$1$3/;

    d> Is it less efficient in some way?

    that assumes the serial number is in slot 1 ($2) and i wouldn't make
    that assumption. the other regex answers match the serial part and not
    the cn part like you do. i was thinking about a more flexible solution
    which would allow any reordering of many parts and no regex could do
    that. hence my idea about split and joining in the desired order.

    uri
     
    Uri Guttman, Mar 31, 2008
    #6
  7. Nope... not if I can create naughty "cn" values:

    this: cn=a\\,cn=b+serialNumber=c,o=x
    becomes serialNumber=c+cn=a\\,cn=b,o=x
    instead of cn=a\\,serialNumber=c+cn=b,o=x

    this: cn=b\+serialNumber=c,o=x
    contains no serialNumber attribute but is modified anyway.

    Not that it matters much when the OP's problem is solved anyway.
    Just pointing out that once you are going to accept things that need
    nontrivial parsing like escape sequences, you have to be careful to
    parse it correctly. Though my variant missed out too, it should
    have ended with (?=$|[+,]) to cover the last component as well.
     
    Hallvard B Furuseth, Apr 2, 2008
    #7
  8. SecureIT

    szr Guest

    Well, my example assumed proper checks would already by done by the time
    it was invoked. But good points nonetheless.
     
    szr, Apr 2, 2008
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.