Parses the LDAP Data Interchange Format (LDIF)
Author: Dominic Cleal dcl@redha t.com eal
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 |
This lens tries to keep as close as possible to RFC2849 http://tools.ietf.org/html/rfc2849 and OpenLDAP’s ldif(5)
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_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 comment = Util.comment_generic /#[ \t]*/ "# "
Map empty lines, including empty comments
let empty = [ del /#?[ \t]*\n/ "\n" ]
Only eol, don’t include whitespace
let eol = Util.del_str "\n"
The separator for attributes and values
let sep_colon = del /:[ \t]*/ ": "
The separator for attributes and base64 encoded values
let sep_base64 = del /::[ \t]*/ ":: "
Format of an LDAP OID from RFC 2251
let ldapoid_re = /[0-9][0-9\.]*/
Separator between modify operations
let sep_modspec = Util.del_str "-" . eol
version-spec = “version:” FILL version-number
let attr_version = Build.key_value_line "version" sep_colon (store /[0-9]+/)
dn-spec = “dn:” (FILL distinguishedName / “:” FILL base64-distinguishedName)
let attr_dn = del /dn/i "dn" . ( attr_safe_string | attr_base64_string ) . eol
AttributeType = ldap-oid / (ALPHA *(attr-type-chars))
let attr_type = ldapoid_re | /[a-zA-Z][a-zA-Z0-9-]*/ - /dn/i - /changeType/i - /include/i
options = option / (option “;” options)
let attr_option = Util.del_str ";" . [ label "@option" . store /[a-zA-Z0-9-]+/ ]
Attribute name, possibly with options
let attr_description = key attr_type . attr_option*
Generic attribute with a value
let attr_val_spec = [ attr_description . ( attr_safe_string | attr_base64_string | attr_url_string ) . eol ]
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
Parses an attribute line with a DN on the RHS Parameters: k:regexp - match attribute name as key
let attr_dn_value (k:regexp) = [ key k . ( attr_safe_string | attr_base64_string ) . eol ]
let sep_line = empty | comment
OpenLDAP extension, must be separated by blank lines
let attr_include = eol . [ key "include" . sep_colon . store /[^ \t\n][^\n]*/ . eol . comment* . eol ]
let sep_record = ( sep_line | attr_include )*
ldif-attrval-record = dn-spec SEP 1*attrval-spec
let ldif_attrval_record = [ seq "record" . attr_dn . ( sep_line* . attr_val_spec )+ ]
ldif-content = version-spec 1*(1*SEP ldif-attrval-record)
let ldif_content = [ label "@content" . ( sep_record . attr_version )? . ( sep_record . ldif_attrval_record )+ . sep_record ]
change-add = “add” SEP 1*attrval-spec
let change_add = [ attr_changetype "add" ] . ( sep_line* . attr_val_spec )+
change-delete = “add” SEP 1*attrval-spec
let change_delete = [ attr_changetype "delete" ]
change-modspec = add/delete/replace: AttributeDesc SEP *attrval-spec “-”
let change_modspec = attr_modspec . ( sep_line* . attr_val_spec )*
change-modify = “modify” SEP *mod-spec
let change_modify = [ attr_changetype "modify" ] . ( sep_line* . [ change_modspec . sep_line* . sep_modspec ] )+
(“modrdn” / “moddn”) SEP newrdn/newsuperior/deleteoldrdn
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
changerecord = “changetype:” FILL (changeadd/delete/modify/moddn)
let change_record = ( change_add | change_delete | change_modify | change_modrdn)
“control:” FILL ldap-oid 0*1(1*SPACE (“true” / “false”)) 0*1(value-spec)
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 ]
ldif-change-record = dn-spec SEP *control changerecord
let ldif_change_record = [ seq "record" . attr_dn . ( ( sep_line | change_control )* . change_control )? . sep_line* . change_record ]
ldif-changes = version-spec 1*(1*SEP ldif-change-record)
let ldif_changes = [ label "@changes" . ( sep_record . attr_version )? . ( sep_record . ldif_change_record )+ . sep_record ]
let lns = sep_record | ldif_content | ldif_changes