# Ldif

Parses the LDAP Data Interchange Format (LDIF)

Author: Dominic Cleal dcl.nosp@m.eal@redha.nosp@m.t.com

Summary

Ldif | Parses the LDAP Data Interchange Format (LDIF)
Reference | This lens tries to keep as close as possible to RFC2849 http://tools.ietf.org/html/rfc2849 and OpenLDAP’s ldif(5)
Licence | This file is licensed under the LGPLv2+, like the rest of Augeas.
USEFUL PRIMITIVES |
comment |
empty | Map empty lines, including empty comments
eol | Only eol, don’t include whitespace
sep_colon | The separator for attributes and values
sep_base64 | The separator for attributes and base64 encoded values
sep_url | The separator for attributes and URL-sourced values
ldapoid_re | Format of an LDAP OID from RFC 2251
sep_modspec | Separator between modify operations
BASIC ATTRIBUTES |
attr_version | version-spec = “version:” FILL version-number
attr_dn | dn-spec = “dn:” (FILL distinguishedName / “:” FILL base64-distinguishedName)
attr_type | AttributeType = ldap-oid / (ALPHA *(attr-type-chars))
attr_option | options = option / (option “;” options)
attr_description | Attribute name, possibly with options
attr_val_spec | Generic attribute with a value
attr_changetype |
attr_modspec |
attr_dn_value | Parses an attribute line with a DN on the RHS Parameters: k:regexp - match attribute name as key
sep_line |
attr_include | OpenLDAP extension, must be separated by blank lines
sep_record |
LDIF CONTENT RECORDS |
ldif_attrval_record | ldif-attrval-record = dn-spec SEP 1*attrval-spec
ldif_content | ldif-content = version-spec 1*(1*SEP ldif-attrval-record)
LDIF CHANGE RECORDS |
change_add | change-add = “add” SEP 1*attrval-spec
change_delete | change-delete = “add” SEP 1*attrval-spec
change_modspec | change-modspec = add/delete/replace: AttributeDesc SEP *attrval-spec “-”
change_modify | change-modify = “modify” SEP *mod-spec
change_modrdn | (“modrdn” / “moddn”) SEP newrdn/newsuperior/deleteoldrdn
change_record | changerecord = “changetype:” FILL (changeadd/delete/modify/moddn)
change_control | “control:” FILL ldap-oid 0*1(1*SPACE (“true” / “false”)) 0*1(value-spec)
ldif_change_record | ldif-change-record = dn-spec SEP *control changerecord
ldif_changes | ldif-changes = version-spec 1*(1*SEP ldif-change-record)
LENS |
lns |

### Reference

This lens tries to keep as close as possible to RFC2849 http://tools.ietf.org/html/rfc2849 and OpenLDAP’s ldif(5)

### Licence

This file is licensed under the LGPLv2+, like the rest of Augeas.

### USEFUL PRIMITIVES

### comment

> let comment = Util.comment_generic /#[ \t]*/ "# "

### empty

> let empty = [ del /#?[ \t]*\n/ "\n" ]

Map empty lines, including empty comments

### eol

> let eol = Util.del_str "\n"

Only eol, don’t include whitespace

### sep_colon

> let sep_colon = del /:[ \t]*/ ": "

The separator for attributes and values

### sep_base64

> let sep_base64 = del /::[ \t]*/ ":: "

The separator for attributes and base64 encoded values

### sep_url

The separator for attributes and URL-sourced values

### ldapoid_re

> let ldapoid_re = /[0-9][0-9\.]*/

Format of an LDAP OID from RFC 2251

### sep_modspec

> let sep_modspec = Util.del_str "-" . eol

Separator between modify operations

### BASIC ATTRIBUTES

### attr_version

> let attr_version = Build.key_value_line "version" sep_colon (store /[0-9]+/)

version-spec = “version:” FILL version-number

### attr_dn

> let attr_dn = del /dn/i "dn" . ( attr_safe_string | attr_base64_string ) . eol

dn-spec = “dn:” (FILL distinguishedName / “:” FILL base64-distinguishedName)

### attr_type

> let attr_type = ldapoid_re | /[a-zA-Z][a-zA-Z0-9-]*/ - /dn/i - /changeType/i - /include/i

AttributeType = ldap-oid / (ALPHA *(attr-type-chars))

### attr_option

> let attr_option = Util.del_str ";" . [ label "@option" . store /[a-zA-Z0-9-]+/ ]

options = option / (option “;” options)

### attr_description

> let attr_description = key attr_type . attr_option*

Attribute name, possibly with options

### attr_val_spec

> let attr_val_spec = [ attr_description . ( attr_safe_string | attr_base64_string | attr_url_string ) . eol ]

Generic attribute with a value

### attr_changetype

> let attr_changetype (t:regexp) = key /changeType/i . sep_colon . store t . eol

#### Parameters

t:regexp | value of changeType

### attr_modspec

> let attr_modspec = key /add|delete|replace/ . sep_colon . store attr_type . attr_option* . eol

### attr_dn_value

> let attr_dn_value (k:regexp) = [ key k . ( attr_safe_string | attr_base64_string ) . eol ]

Parses an attribute line with a DN on the RHS Parameters: k:regexp - match attribute name as key

### sep_line

> let sep_line = empty | comment

### attr_include

> let attr_include = eol . [ key "include" . sep_colon . store /[^ \t\n][^\n]*/ . eol . comment* . eol ]

OpenLDAP extension, must be separated by blank lines

### sep_record

> let sep_record = ( sep_line | attr_include )*

### LDIF CONTENT RECORDS

### ldif_attrval_record

> let ldif_attrval_record = [ seq "record" . attr_dn . ( sep_line* . attr_val_spec )+ ]

ldif-attrval-record = dn-spec SEP 1*attrval-spec

### ldif_content

> let ldif_content = [ label "@content" . ( sep_record . attr_version )? . ( sep_record . ldif_attrval_record )+ . sep_record ]

ldif-content = version-spec 1*(1*SEP ldif-attrval-record)

### LDIF CHANGE RECORDS

### change_add

> let change_add = [ attr_changetype "add" ] . ( sep_line* . attr_val_spec )+

change-add = “add” SEP 1*attrval-spec

### change_delete

> let change_delete = [ attr_changetype "delete" ]

change-delete = “add” SEP 1*attrval-spec

### change_modspec

> let change_modspec = attr_modspec . ( sep_line* . attr_val_spec )*

change-modspec = add/delete/replace: AttributeDesc SEP *attrval-spec “-”

### change_modify

> let change_modify = [ attr_changetype "modify" ] . ( sep_line* . [ change_modspec . sep_line* . sep_modspec ] )+

change-modify = “modify” SEP *mod-spec

### change_modrdn

> let change_modrdn = let attr_deleteoldrdn = [ key "deleteoldrdn" . attr_intflag . eol ] in let attrs_modrdn = attr_dn_value "newrdn" | attr_dn_value "newsuperior" | attr_deleteoldrdn in [ attr_changetype /modr?dn/ ] . ( sep_line | attrs_modrdn )* . attrs_modrdn

(“modrdn” / “moddn”) SEP newrdn/newsuperior/deleteoldrdn

### change_record

> let change_record = ( change_add | change_delete | change_modify | change_modrdn)

changerecord = “changetype:” FILL (changeadd/delete/modify/moddn)

### change_control

> let change_control = let attr_criticality = [ Util.del_ws_spc . label "criticality" . store /true|false/ ] in let attr_ctrlvalue = [ label "value" . (attr_safe_string | attr_base64_string | attr_url_string ) ] in [ key "control" . sep_colon . store ldapoid_re . attr_criticality? . attr_ctrlvalue? . eol ]

”control:” FILL ldap-oid 0*1(1*SPACE (“true” / “false”)) 0*1(value-spec)

### ldif_change_record

> let ldif_change_record = [ seq "record" . attr_dn . ( ( sep_line | change_control )* . change_control )? . sep_line* . change_record ]

ldif-change-record = dn-spec SEP *control changerecord

### ldif_changes

> let ldif_changes = [ label "@changes" . ( sep_record . attr_version )? . ( sep_record . ldif_change_record )+ . sep_record ]

ldif-changes = version-spec 1*(1*SEP ldif-change-record)

### LENS

### lns

> let lns = sep_record | ldif_content | ldif_changes

> let comment = Util.comment_generic /#[ \t]*/ "# "

> let empty = [ del /#?[ \t]*\n/ "\n" ]

Map empty lines, including empty comments

> let eol = Util.del_str "\n"

Only eol, don’t include whitespace

> let sep_colon = del /:[ \t]*/ ": "

The separator for attributes and values

> let sep_base64 = del /::[ \t]*/ ":: "

The separator for attributes and base64 encoded values

> let ldapoid_re = /[0-9][0-9\.]*/

Format of an LDAP OID from RFC 2251

> let sep_modspec = Util.del_str "-" . eol

Separator between modify operations

> let attr_version = Build.key_value_line "version" sep_colon (store /[0-9]+/)

version-spec = “version:” FILL version-number

> let attr_dn = del /dn/i "dn" . ( attr_safe_string | attr_base64_string ) . eol

dn-spec = “dn:” (FILL distinguishedName / “:” FILL base64-distinguishedName)

> let attr_type = ldapoid_re | /[a-zA-Z][a-zA-Z0-9-]*/ - /dn/i - /changeType/i - /include/i

AttributeType = ldap-oid / (ALPHA *(attr-type-chars))

> let attr_option = Util.del_str ";" . [ label "@option" . store /[a-zA-Z0-9-]+/ ]

options = option / (option “;” options)

> let attr_description = key attr_type . attr_option*

Attribute name, possibly with options

> let attr_val_spec = [ attr_description . ( attr_safe_string | attr_base64_string | attr_url_string ) . eol ]

Generic attribute with a value

> let attr_changetype (t:regexp) = key /changeType/i . sep_colon . store t . eol

> let attr_modspec = key /add|delete|replace/ . sep_colon . store attr_type . attr_option* . eol

> let attr_dn_value (k:regexp) = [ key k . ( attr_safe_string | attr_base64_string ) . eol ]

Parses an attribute line with a DN on the RHS Parameters: k:regexp - match attribute name as key

> let sep_line = empty | comment

> let attr_include = eol . [ key "include" . sep_colon . store /[^ \t\n][^\n]*/ . eol . comment* . eol ]

OpenLDAP extension, must be separated by blank lines

> let sep_record = ( sep_line | attr_include )*

> let ldif_attrval_record = [ seq "record" . attr_dn . ( sep_line* . attr_val_spec )+ ]

ldif-attrval-record = dn-spec SEP 1*attrval-spec

> let ldif_content = [ label "@content" . ( sep_record . attr_version )? . ( sep_record . ldif_attrval_record )+ . sep_record ]

ldif-content = version-spec 1*(1*SEP ldif-attrval-record)

> let change_add = [ attr_changetype "add" ] . ( sep_line* . attr_val_spec )+

change-add = “add” SEP 1*attrval-spec

> let change_delete = [ attr_changetype "delete" ]

change-delete = “add” SEP 1*attrval-spec

> let change_modspec = attr_modspec . ( sep_line* . attr_val_spec )*

change-modspec = add/delete/replace: AttributeDesc SEP *attrval-spec “-”

> let change_modify = [ attr_changetype "modify" ] . ( sep_line* . [ change_modspec . sep_line* . sep_modspec ] )+

change-modify = “modify” SEP *mod-spec

> let change_modrdn = let attr_deleteoldrdn = [ key "deleteoldrdn" . attr_intflag . eol ] in let attrs_modrdn = attr_dn_value "newrdn" | attr_dn_value "newsuperior" | attr_deleteoldrdn in [ attr_changetype /modr?dn/ ] . ( sep_line | attrs_modrdn )* . attrs_modrdn

(“modrdn” / “moddn”) SEP newrdn/newsuperior/deleteoldrdn

> let change_record = ( change_add | change_delete | change_modify | change_modrdn)

changerecord = “changetype:” FILL (changeadd/delete/modify/moddn)

> let change_control = let attr_criticality = [ Util.del_ws_spc . label "criticality" . store /true|false/ ] in let attr_ctrlvalue = [ label "value" . (attr_safe_string | attr_base64_string | attr_url_string ) ] in [ key "control" . sep_colon . store ldapoid_re . attr_criticality? . attr_ctrlvalue? . eol ]

“control:” FILL ldap-oid 0*1(1*SPACE (“true” / “false”)) 0*1(value-spec)

> let ldif_change_record = [ seq "record" . attr_dn . ( ( sep_line | change_control )* . change_control )? . sep_line* . change_record ]

ldif-change-record = dn-spec SEP *control changerecord

> let ldif_changes = [ label "@changes" . ( sep_record . attr_version )? . ( sep_record . ldif_change_record )+ . sep_record ]

ldif-changes = version-spec 1*(1*SEP ldif-change-record)

> let lns = sep_record | ldif_content | ldif_changes

Close