Ldif

Parses the LDAP Data Interchange Format (LDIF)

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

Summary
LdifParses the LDAP Data Interchange Format (LDIF)
ReferenceThis lens tries to keep as close as possible to RFC2849 http://tools.ietf.org/html/rfc2849 and OpenLDAP’s ldif(5)
LicenceThis file is licensed under the LGPLv2+, like the rest of Augeas.
USEFUL PRIMITIVES
comment
emptyMap empty lines, including empty comments
eolOnly eol, don’t include whitespace
sep_colonThe separator for attributes and values
sep_base64The separator for attributes and base64 encoded values
sep_urlThe separator for attributes and URL-sourced values
ldapoid_reFormat of an LDAP OID from RFC 2251
sep_modspecSeparator between modify operations
BASIC ATTRIBUTES
attr_versionversion-spec = “version:” FILL version-number
attr_dndn-spec = “dn:” (FILL distinguishedName / “:” FILL base64-distinguishedName)
attr_typeAttributeType = ldap-oid / (ALPHA *(attr-type-chars))
attr_optionoptions = option / (option “;” options)
attr_descriptionAttribute name, possibly with options
attr_val_specGeneric attribute with a value
attr_changetype
attr_modspec
attr_dn_valueParses an attribute line with a DN on the RHS Parameters: k:regexp - match attribute name as key
sep_line
attr_includeOpenLDAP extension, must be separated by blank lines
sep_record
LDIF CONTENT RECORDS
ldif_attrval_recordldif-attrval-record = dn-spec SEP 1*attrval-spec
ldif_contentldif-content = version-spec 1*(1*SEP ldif-attrval-record)
LDIF CHANGE RECORDS
change_addchange-add = “add” SEP 1*attrval-spec
change_deletechange-delete = “add” SEP 1*attrval-spec
change_modspecchange-modspec = add/delete/replace: AttributeDesc SEP *attrval-spec “-”
change_modifychange-modify = “modify” SEP *mod-spec
change_modrdn(“modrdn” / “moddn”) SEP newrdn/newsuperior/deleteoldrdn
change_recordchangerecord = “changetype:” FILL (changeadd/delete/modify/moddn)
change_control“control:” FILL ldap-oid 0*1(1*SPACE (“true” / “false”)) 0*1(value-spec)
ldif_change_recordldif-change-record = dn-spec SEP *control changerecord
ldif_changesldif-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:regexpvalue 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