}
}
- if (want_bindpw)
+ if (want_bindpw) {
passwd.bv_val = getpassphrase("Enter LDAP Password: ");
passwd.bv_len = strlen( passwd.bv_val );
+ }
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
}
}
- if (want_bindpw)
+ if (want_bindpw) {
passwd.bv_val = getpassphrase("Enter LDAP Password: ");
passwd.bv_len = strlen( passwd.bv_val );
+ }
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
}
}
- if (want_bindpw)
+ if (want_bindpw) {
passwd.bv_val = getpassphrase("Enter LDAP Password: ");
passwd.bv_len = strlen( passwd.bv_val );
+ }
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
+++ /dev/null
-LDAP Data Interchange Format (LDIF) Gordon Good
-INTERNET-DRAFT Netscape Communications
-Status: Standards-Track 19 October 1999
-
- The LDAP Data Interchange Format (LDIF) - Technical Specification
- Filename: draft-good-ldap-ldif-05.txt
-
-Status of this Memo
-
- This document is an Internet-Draft and is in full conformance
- with all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet Engineering
- Task Force (IETF), its areas, and its working groups. Note that
- other groups may also distribute working documents as
- Internet-Drafts.
-
- Internet-Drafts are draft documents valid for a maximum of six
- months and may be updated, replaced, or obsoleted by other
- documents at any time. It is inappropriate to use Internet-
- Drafts as reference material or to cite them other than as
- "work in progress."
-
- To view the list Internet-Draft Shadow Directories, see
- http://www.ietf.org/shadow.html.
-
- This Internet Draft expires 19 April, 2000.
-
-
-Abstract
-
- This document describes a file format suitable for describing
- directory information or modifications made to directory information.
- The file format, known as LDIF, for LDAP Data Interchange Format, is
- typically used to import and export directory information between
- LDAP-based directory servers, or to describe a set of changes which
- are to be applied to a directory.
-
-
-Background and Intended Usage
-
- There are a number of situations where a common interchange format is
- desirable. For example, one might wish to export a copy of the
- contents of a directory server to a file, move that file to a
- different machine, and import the contents into a second directory
- server.
-
- Additionally, by using a well-defined interchange format, development
-
-
-
-Good October 18, 1999 [Page 1]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- of data import tools from legacy systems is facilitated. A fairly
- simple set of tools written in awk or perl can, for example, convert
- a database of personnel information into an LDIF file. This file can
- then be imported into a directory server, regardless of the internal
- database representation the target directory server uses.
-
- The LDIF format was originally developed and used in the University
- of Michigan LDAP implementation. The first use of LDIF was in
- describing directory entries. Later, the format was expanded to
- allow representation of changes to directory entries.
-
- Relationship to the application/directory MIME content-type:
-
- The application/directory MIME content-type [1] is a general
- framework and format for conveying directory information, and is
- independent of any particular directory service. The LDIF format is
- a simpler format which is perhaps easier to create, and may also be
- used, as noted, to describe a set of changes to be applied to a
- directory.
-
- The key words "MUST", "MAY", and "SHOULD" used in this document are
- to be interpreted as described in [7].
-
-
-Definition of the LDAP Data Interchange Format
-
-
- The LDIF format is used to convey directory information, or a
- description of a set of changes made to directory entries. An LDIF
- file consists of a series of records separated by line separators. A
- record consists of a sequence of lines describing a directory entry,
- or a sequence of lines describing a set of changes to a directory
- entry. An LDIF file specifies a set of directory entries, or a set
- of changes to be applied to directory entries, but not both.
-
- There is a one-to-one correlation between LDAP operations that modify
- the directory (add, delete, modify, and modrdn), and the types of
- changerecords described below ("add", "delete", "modify", and
- "modrdn" or "moddn"). This correspondence is intentional, and
- permits a straightforward translation from LDIF changerecords to
- protocol operations.
-
-Formal Syntax Definition of LDIF
-
- The following definition uses the augmented Backus-Naur Form
- specified in RFC 2234 [2].
-
- ldif-file = ldif-content / ldif-changes
-
-
-
-Good October 18, 1999 [Page 2]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- ldif-content = version-spec 1*(1*SEP ldif-attrval-record)
-
- ldif-changes = version-spec 1*(1*SEP ldif-change-record)
-
- ldif-attrval-record = dn-spec SEP 1*attrval-spec
-
- ldif-change-record = dn-spec SEP *control changerecord
-
- version-spec = "version:" FILL version-number
-
- version-number = 1*DIGIT
- ; version-number MUST be "1" for the
- ; LDIF format described in this document.
-
- dn-spec = "dn:" (FILL distinguishedName /
- ":" FILL base64-distinguishedName)
-
- distinguishedName = SAFE-UTF8-STRING
- ; a distinguished name, as defined in [3]
-
- base64-distinguishedName = BASE64-UTF8-STRING
- ; a distinguishedName which has been base64
- ; encoded (see note 10, below)
-
- rdn = SAFE-UTF8-STRING
- ; a relative distinguished name, defined as
- ; <name-component> in [3]
-
- base64-rdn = BASE64-UTF8-STRING
- ; an rdn which has been base64 encoded (see
- ; note 10, below)
-
- control = "control:" FILL ldap-oid ; controlType
- 0*1(1*SPACE ("true" / "false")) ; criticality
- 0*1(value-spec) ; controlValue
- SEP
- ; (See note 9, below)
-
- ldap-oid = 1*DIGIT 0*1("." 1*DIGIT)
- ; An LDAPOID, as defined in [4]
-
- attrval-spec = AttributeDescription value-spec SEP
-
- value-spec = ":" ( FILL 0*1(SAFE-STRING) /
- ":" FILL (BASE64-STRING) /
- "<" FILL url)
- ; See notes 7 and 8, below
-
-
-
-
-Good October 18, 1999 [Page 3]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- url = <a Uniform Resource Locator, as defined in [6]>
- ; (See Note 6, below)
-
- AttributeDescription = AttributeType [";" options]
- ; Definition taken from [4]
-
- AttributeType = ldap-oid / (ALPHA *(attr-type-chars))
-
- options = option / (option ";" options)
-
- option = 1*opt-char
-
- attr-type-chars = ALPHA / DIGIT / "-"
-
- opt-char = attr-type-chars
-
- changerecord = "changetype:" FILL
- (change-add / change-delete /
- change-modify / change-moddn)
-
- change-add = "add" SEP 1*attrval-spec
-
- change-delete = "delete" SEP
-
- change-moddn = ("modrdn" / "moddn") SEP
- "newrdn:" ( FILL rdn /
- ":" FILL base64-rdn) SEP
- "deleteoldrdn:" FILL ("0" / "1") SEP
- 0*1("newsuperior:"
- ( FILL distinguishedName /
- ":" FILL base64-distinguishedName) SEP)
-
- change-modify = "modify" SEP *mod-spec
-
- mod-spec = ("add:" / "delete:" / "replace:")
- FILL AttributeDescription SEP
- *attrval-spec
- "-" SEP
-
- SPACE = %x20
- ; ASCII SP, space
-
- FILL = *SPACE
-
- SEP = (CR LF / LF)
-
- CR = %x0D
- ; ASCII CR, carriage return
-
-
-
-Good October 18, 1999 [Page 4]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- LF = %x0A
- ; ASCII LF, line feed
-
- ALPHA = %x41-5A / %x61-7A
- ; A-Z / a-z
-
- DIGIT = %x30-39
- ; 0-9
-
- UTF8-1 = %x80-BF
-
- UTF8-2 = %xC0-DF UTF8-1
-
- UTF8-3 = %xE0-EF 2UTF8-1
-
- UTF8-4 = %xF0-F7 3UTF8-1
-
- UTF8-5 = %xF8-FB 4UTF8-1
-
- UTF8-6 = %xFC-FD 5UTF8-1
-
- SAFE-CHAR = %x01-09 / %x0B-0C / %x0E-7F
- ; any value <= 127 decimal except NUL, LF, and CR
-
- SAFE-INIT-CHAR = %x01-09 / %x0B-0C / %x0E-1F /
- %x21-39 / %x3B / %x3D-7F
- ; any value <= 127 except NUL, LF, CR,
- ; SPACE, colon (":", ASCII 58 decimal)
- ; and less-than ("<" , ASCII 60 decimal)
-
- SAFE-STRING = [SAFE-INIT-CHAR *SAFE-CHAR]
-
- SAFE-UTF8-CHAR = SAFE-CHAR / UTF8-2 / UTF8-3 /
- UTF8-4 / UTF8-5 / UTF8-6
-
- SAFE-INIT-UTF8-CHAR = SAFE-INIT-CHAR / UTF8-2 / UTF8-3 /
- UTF8-4 / UTF8-5 / UTF8-6
-
- SAFE-UTF8-STRING = [SAFE-INIT-UTF8-CHAR *SAFE-UTF8-CHAR]
-
- BASE64-UTF8-STRING = BASE64-STRING
- ; MUST be the base64 encoding of a valid
- ; string of UTF-8 characters
-
- BASE64-CHAR = %x2B / %x2F / %x30-39 / %x3D / %x41-5A / %x61-7A
- ; +, /, 0-9, =, A-Z, and a-z
- ; as specified in [5]
-
-
-
-
-Good October 18, 1999 [Page 5]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- BASE64-STRING = [*(BASE64-CHAR)]
-
-
- Notes on LDIF Syntax
-
- 1) For the LDIF format described in this document, the version number
- MUST be "1". If the version number is absent, implementations MAY
- choose to interpret the contents as an older LDIF file format,
- supported by the University of Michigan ldap-3.3 implementation [8].
-
- 2) Any non-empty line, including comment lines, in an LDIF file MAY
- be folded by inserting a line separator (SEP) and a SPACE. Folding
- MUST NOT occur before the first character of the line. In other
- words, folding a line into two lines, the first of which is empty, is
- not permitted. Any line that begins with a single space MUST be
- treated as a continuation of the previous (non-empty) line. When
- joining folded lines, exactly one space character at the beginning of
- each continued line must be discarded. Implementations SHOULD NOT
- fold lines in the middle of a multi-byte UTF-8 character.
-
- 3) Any line that begins with a pound-sign ("#", ASCII 35) is a
- comment line, and MUST be ignored when parsing an LDIF file.
-
- 4) Any dn or rdn that contains characters other than those defined as
- "SAFE-UTF8-CHAR", or begins with a character other than those defined
- as "SAFE-INIT-UTF8-CHAR", above, MUST be base-64 encoded. Other
- values MAY be base-64 encoded. Any value that contains characters
- other than those defined as "SAFE-CHAR", or begins with a character
- other than those defined as "SAFE-INIT-CHAR", above, MUST be base-64
- encoded. Other values MAY be base-64 encoded.
-
- 5) When a zero-length attribute value is to be included directly in
- an LDIF file, it MUST be represented as AttributeDescription ":" FILL
- SEP. For example, "seeAlso:" followed by a newline represents a
- zero-length "seeAlso" attribute value. It is also permissible for
- the value referred to by a URL to be of zero length.
-
- 6) When a URL is specified in an attrval-spec, the following
- conventions apply:
- a) Implementations SHOULD support the file:// URL format. The
- contents of the referenced file are to be included verbatim
- in the interpreted output of the LDIF file.
- b) Implementations MAY support other URL formats. The semantics
- associated with each supported URL will be documented in
- an associated Applicability Statement.
-
- 7) Distinguished names, relative distinguished names, and attribute
- values of DirectoryString syntax MUST be valid UTF-8 strings.
-
-
-
-Good October 18, 1999 [Page 6]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- Implementations that read LDIF MAY interpret files in which these
- entities are stored in some other character set encoding, but
- implementations MUST NOT generate LDIF content which does not contain
- valid UTF-8 data.
-
- 8) Values or distinguished names that end with SPACE SHOULD be base-
- 64 encoded.
-
- 9) When controls are included in an LDIF file, implementations MAY
- choose to ignore some or all of them. This may be necessary if the
- changes described in the LDIF file are being sent on an LDAPv2
- connection (LDAPv2 does not support controls), or the particular
- controls are not supported by the remote server. If the criticality
- of a control is "true", then the implementation MUST either include
- the control, or MUST NOT send the operation to a remote server.
-
- 10) When an attrval-spec, distinguishedName, or rdn is base64-
- encoded, the encoding rules specified in [5] are used with the
- following exceptions: a) The requirement that base64 output streams
- must be represented as lines of no more than 76 characters is
- removed. Lines in LDIF files may only be folded according to the
- folding rules described in note 2, above. b) Base64 strings in [5]
- may contain characters other than those defined in BASE64-CHAR, and
- are ignored. LDIF does not permit any extraneous characters, other
- than those used for line folding.
-
-Examples of LDAP Data Interchange Format
-
-
- Example 1: An simple LDAP file with two entries
-
- version: 1
- dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
- objectclass: top
- objectclass: person
- objectclass: organizationalPerson
- cn: Barbara Jensen
- cn: Barbara J Jensen
- cn: Babs Jensen
- sn: Jensen
- uid: bjensen
- telephonenumber: +1 408 555 1212
- description: A big sailing fan.
-
- dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com
- objectclass: top
- objectclass: person
- objectclass: organizationalPerson
-
-
-
-Good October 18, 1999 [Page 7]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- cn: Bjorn Jensen
- sn: Jensen
- telephonenumber: +1 408 555 1212
-
- Example 2: A file containing an entry with a folded attribute value
-
- version: 1
- dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
- objectclass:top
- objectclass:person
- objectclass:organizationalPerson
- cn:Barbara Jensen
- cn:Barbara J Jensen
- cn:Babs Jensen
- sn:Jensen
- uid:bjensen
- telephonenumber:+1 408 555 1212
- description:Babs is a big sailing fan, and travels extensively in sea
- rch of perfect sailing conditions.
- title:Product Manager, Rod and Reel Division
-
- Example 3: A file containing a base-64-encoded value
-
- version: 1
- dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com
- objectclass: top
- objectclass: person
- objectclass: organizationalPerson
- cn: Gern Jensen
- cn: Gern O Jensen
- sn: Jensen
- uid: gernj
- telephonenumber: +1 408 555 1212
- description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVlIGlzIGJ
- hc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdGVyIGluIGl0ICh
- hIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQgb3V0IG1vcmUu
-
- Example 4: A file containing an entries with UTF-8-encoded attribute
- values, including language tags. Comments indicate the contents
- of UTF-8-encoded attributes and distinguished names.
-
- version: 1
- dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
- # dn:: ou=<JapaneseOU>,o=Airius
- objectclass: top
- objectclass: organizationalUnit
- ou:: 5Za25qWt6YOo
- # ou:: <JapaneseOU>
-
-
-
-Good October 18, 1999 [Page 8]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- ou;lang-ja:: 5Za25qWt6YOo
- # ou;lang-ja:: <JapaneseOU>
- ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
- # ou;lang-ja:: <JapaneseOU_in_phonetic_representation>
- ou;lang-en: Sales
- description: Japanese office
-
- dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
- # dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius
- userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
- objectclass: top
- objectclass: person
- objectclass: organizationalPerson
- objectclass: inetOrgPerson
- uid: rogasawara
- mail: rogasawara@airius.co.jp
- givenname;lang-ja:: 44Ot44OJ44OL44O8
- # givenname;lang-ja:: <JapaneseGivenname>
- sn;lang-ja:: 5bCP56yg5Y6f
- # sn;lang-ja:: <JapaneseSn>
- cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
- # cn;lang-ja:: <JapaneseCn>
- title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
- # title;lang-ja:: <JapaneseTitle>
- preferredlanguage: ja
- givenname:: 44Ot44OJ44OL44O8
- # givenname:: <JapaneseGivenname>
- sn:: 5bCP56yg5Y6f
- # sn:: <JapaneseSn>
- cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
- # cn:: <JapaneseCn>
- title:: 5Za25qWt6YOoIOmDqOmVtw==
- # title:: <JapaneseTitle>
- givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
- # givenname;lang-ja;phonetic::
- <JapaneseGivenname_in_phonetic_representation_kana>
- sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
- # sn;lang-ja;phonetic:: <JapaneseSn_in_phonetic_representation_kana>
- cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
- # cn;lang-ja;phonetic:: <JapaneseCn_in_phonetic_representation_kana>
- title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
- # title;lang-ja;phonetic:: <JapaneseTitle_in_phonetic_representation_kana>
- givenname;lang-en: Rodney
- sn;lang-en: Ogasawara
- cn;lang-en: Rodney Ogasawara
- title;lang-en: Sales, Director
-
- Example 5: A file containing a reference to an external file
-
-
-
-Good October 18, 1999 [Page 9]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- version: 1
- dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
- objectclass: top
- objectclass: person
- objectclass: organizationalPerson
- cn: Horatio Jensen
- cn: Horatio N Jensen
- sn: Jensen
- uid: hjensen
- telephonenumber: +1 408 555 1212
- jpegphoto:< file:///usr/local/directory/photos/hjensen.jpg
-
- Example 6: A file containing a series of change records and comments
-
- version: 1
- # Add a new entry
- dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
- changetype: add
- objectclass: top
- objectclass: person
- objectclass: organizationalPerson
- cn: Fiona Jensen
- sn: Jensen
- uid: fiona
- telephonenumber: +1 408 555 1212
- jpegphoto:< file:///usr/local/directory/photos/fiona.jpg
-
- # Delete an existing entry
- dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
- changetype: delete
-
- # Modify an entry's relative distinguished name
- dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
- changetype: modrdn
- newrdn: cn=Paula Jensen
- deleteoldrdn: 1
-
- # Rename an entry and move all of its children to a new location in
- # the directory tree (only implemented by LDAPv3 servers).
- dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
- changetype: modrdn
- newrdn: ou=Product Development Accountants
- deleteoldrdn: 0
- newsuperior: ou=Accounting, dc=airius, dc=com
-
- # Modify an entry: add an additional value to the postaladdress attribute,
- # completely delete the description attribute, replace the telephonenumber
- # attribute with two values, and delete a specific value from the
-
-
-
-Good October 18, 1999 [Page 10]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- # facsimiletelephonenumber attribute
- dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
- changetype: modify
- add: postaladdress
- postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
- -
- delete: description
- -
- replace: telephonenumber
- telephonenumber: +1 408 555 1234
- telephonenumber: +1 408 555 5678
- -
- delete: facsimiletelephonenumber
- facsimiletelephonenumber: +1 408 555 9876
- -
-
- # Modify an entry: replace the postaladdress attribute with an empty
- # set of values (which will cause the attribute to be removed), and
- # delete the entire description attribute. Note that the first will
- # always succeed, while the second will only succeed if at least
- # one value for the description attribute is present.
- dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com
- changetype: modify
- replace: postaladdress
- -
- delete: description
- -
-
- Example 7: An LDIF file containing a change record with a control
- version: 1
- # Delete an entry. The operation will attach the LDAPv3
- # Tree Delete Control defined in [9]. The criticality
- # field is "true" and the controlValue field is
- # absent, as required by [9].
- dn: ou=Product Development, dc=airius, dc=com
- control: 1.2.840.113556.1.4.805 true
- changetype: delete
-
-
-Security Considerations
-
- Given typical directory applications, an LDIF file is likely to
- contain sensitive personal data. Appropriate measures should be
- taken to protect the privacy of those persons whose data is contained
- in an LDIF file.
-
- Since ":<" directives can cause external content to be included when
- processing an LDIF file, one should be cautious of accepting LDIF
-
-
-
-Good October 18, 1999 [Page 11]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- files from external sources. A "trojan" LDIF file could name a file
- with sensitive contents and cause it to be included in a directory
- entry, which a hostile entity could read via LDAP.
-
- LDIF does not provide any method for carrying authentication
- information with an LDIF file. Users of LDIF files must take care to
- verify the integrity of an LDIF file received from an external
- source.
-
-Appendix A: Differences from previous versions of this document
-
- This section summarizes the differences between previous revisions of
- this draft, as an aid to document reviewers. This section will be
- deleted prior to publication as an RFC.
-
- Differences between draft-ietf-asid-ldif-00.txt and draft-ietf-asid-
- ldif-01.txt
-
- 1) The BNF has been modified to explicitly disallow ldif content and
- change records in the same file. In other words, a given LDIF file
- is either a series of directory entries, or a series of
- modifications. An LDIF file MUST NOT contain both types of records.
-
- 2) External references are now URLs, instead of simple filenames.
-
- 3) The BNF has been modified to allow base-64-encoded distinguished
- names.
-
- 4) Multiple separators are now permitted between records.
-
- Differences between draft-ietf-asid-ldif-01.txt and draft-ietf-asid-
- ldif-02.txt
-
- 1) The BNF has been modified such that a simple attribute name
- ("attrname") has been replaced with an "attribute-description" as
- defined in the LDAPv3 protocol document [4]. This permits language
- codes and other attribute options to be carried in an LDIF file.
-
- 2) A new option, "charset", may be used in attribute descriptions.
- This facilitates multi-lingual character set conversion.
-
- 3) The definition of the "safe" and "safe-initval" productions has
- been relaxed to allow non-ASCII characters with values greater than
- 126. This permits more natural expression of character sets such as
- Latin-1 in LDIF files.
-
- Differences between draft-ietf-asid-ldif-02.txt and draft-good-ldap-
- ldif-00.txt
-
-
-
-Good October 18, 1999 [Page 12]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- 1) The "charset-option" and "charset-name" productions were removed
- from the BNF, due to objections within the working group. UTF-8 is
- the only character set that may be used in LDIF.
-
- 2) Examples were reworked to reflect the above change, and to include
- an example of a non-western language represented in UTF-8.
-
- Differences between draft-ietf-good-ldif-00.txt and draft-good-ldap-
- ldif-01.txt
-
- 1) Added version identifiers to the examples - they were missing.
-
- 2) Clarified that LDIF files must use UTF-8.
-
- Differences between draft-good-ldap-ldif-01.txt and draft-good-ldap-
- ldif-02.txt
-
- 1) Added a recommendation that values ending in SPACE should be
- base-64 encoded.
-
- 2) Clarified the procedure for joining folded lines.
-
- 3) Updated header to reflect new IETF I-D guidelines.
-
- Differences between draft-good-ldap-ldif-02.txt and draft-good-ldap-
- ldif-03.txt
-
- 1) Fixed reference from RFC 1779 to RFC 2253.
-
- 2) Version string is now required.
-
- 3) Comment lines may be folded (this is now explicitly mentioned in
- note 2).
-
- 4) Moved this section (differences between draft versions) to an
- appendix.
-
- 5) Updated examples to use "dc=airius, dc=com" instead of "o=Ace
- Industry, c=US"
-
- 6) Cleaned up references section.
-
- Differences between draft-good-ldap-ldif-03.txt and draft-good-ldap-
- ldif-04.txt
-
- 1) The grammar now requires that an LDIF file end with one or more
- SEP sequences (newlines). This was inadvertently prohibited in
- earlier revisions of the grammar.
-
-
-
-Good October 18, 1999 [Page 13]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- 2) Several minor spelling and typographical errors were fixed.
-
- 3) Reworked the grammar to make it more readable. Hallvard Furuseth
- (University of Oslo) provided the new BNF.
-
- 4) Excluded NUL from "safe" production.
-
- 5) Changed "0,1*xxx" "0*1xxx" in compliance with RFC822.
-
- 6) Fixed a glitch in the grammar that allowed multiple changetypes
- within a single LDIF change record. The intent is that only one
- changetype per change record is permitted.
-
- 7) Fixed a mistake in example 2 (folded attribute value).
-
- 8) The BNF now explicitly requires that zero-length attribute values
- be encoded as attribute-description ":" FILL SEP.
-
- 9) Factored "changetype: FILL" out of the productions for change-add,
- change-delete, change-moddn, and change-modify.
-
- 10) RFC 2251 permits an LDAP modify operation with no modifications,
- and also permits an attribute with no values. Although it's unclear
- what the purpose of these constructs might be, I altered the BNF to
- allow these to be described in LDIF.
-
- 11) The BNF may now carry LDAP v3 controls in ldif-change-records.
- The "value-spec" production was factored out to allow it to be used
- in the definition of a control.
-
- 12) Clarified the rules for line-folding to prohibit a line from
- being folded into two lines, the first of which is empty. This
- guarantees that the sequence SEP SEP terminates an LDIF record, and
- allows, for example, "perl -n00" to be used to read an entire LDIF
- record into the $_ variable.
-
- Differences between draft-good-ldap-ldif-04.txt and draft-good-ldap-
- ldif-05.txt
-
- 1) The grammar has been rewritten to use the RFC2234 ABNF, replacing
- the RFC822 ABNF.
-
- 2) The grammar makes fewer uses of <prose-val>.
-
- 3) DNs, RDNs, and attribute values with DirectoryString are now
- explicitly called out as UTF-8 strings.
-
- 4) An error in the BNF for "control" was fixed.
-
-
-
-Good October 18, 1999 [Page 14]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- 5) An additional ldif-change-record was added to example 6.
-
- 6) Since RFC 1521 defines base-64 encoding with different folding
- rules, and permits illegal characters (which should be ignored), an
- explanatory note has been added. This note explains that lines must
- be folded according to LDIF rules, not RFC 1521 rules, and that
- extraneous characters are not permitted.
-
- 7) DNs, values, and rdns containing octets > 127 must be base-64
- encoded.
-
-
-Acknowledgments
-
- The LDAP Interchange Format was developed as part of the University
- of Michigan LDAP reference implementation, and was developed by Tim
- Howes, Mark Smith, and Gordon Good. It is based in part upon work
- supported by the National Science Foundation under Grant No. NCR-
- 9416667.
-
- Members of the IETF LDAP Extensions Working group provided many
- helpful suggestions. In particular, Hallvard B. Furuseth of the
- University of Oslo made many significant contributions to this
- document, including a thorough review and rewrite of the BNF.
-
-References
-
-
- [1] Howes, T., Smith, M., "A MIME Content-Type for Directory Infor-
- mation", RFC 2425, September 1998,
- <URL:http://www.ietf.org/rfc/rfc2245.txt>
-
- [2] Crocker, D., Overell, P., "Augmented BNF for Syntax Specifica-
- tions: ABNF" , RFC 2234, November 1997,
- <URL:http://ds.internic.net/rfc/rfc2234.txt>
-
- [3] Wahl, M., Kille, S., Howes, T., "A String Representation of Dis-
- tinguished Names", RFC 2253,
- <URL:http://www.ietf.org/rfc/rfc2253.txt>
-
- [4] Wahl, M., Howes, T., Kille, S., "Lightweight Directory Access
- Protocol (v3)", RFC 2251, July, 1997,
- <URL:ftp://www.ietf.org/rfc/rfc2251.txt>
-
- [5] Borenstein, N., Freed, N., "MIME (Multipurpose Internet Mail
- Extensions) Part One: Mechanisms for Specifying and Describing
- the Format of Internet Message Bodies", section 5.2, "Base64
- Content-Transfer-Encoding", RFC 1521, December 1993,
-
-
-
-Good October 18, 1999 [Page 15]
-\f
-INTERNET-DRAFT LDAP Data Interchange Format 19 October 1999
-
-
- <URL:http://ds.internic.net/rfc/rfc1521.txt>
-
- [6] T. Berners-Lee, L. Masinter, M. McCahill, "Uniform Resource
- Locators (URL)", RFC 1738, December 1994,
- <URL:http://ds.internic.net/rfc/rfc1738.txt>
-
- [7] S. Bradner, "Key Words for use in RFCs to Indicate Requirement
- Levels", Harvard University, RFC 2119, March 1997,
- <URL:http://ds.internic.net/rfc/rfc2119.txt>
-
- [8] The SLAPD and SLURPD Administrators Guide. University of Michi-
- gan, April 1996. <URL:
- http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/toc.html>
-
- [9] M. P. Armijo, "Tree Delete Control", Microsoft Corporation,
- INTERNET-DRAFT June 1999, <URL:http://www.ietf.org/internet-
- drafts/draft-armijo-ldap-treedelete-01.txt>
-
-
-
-
-Author's Address
-
- Gordon Good
- Netscape Communications Corp.
- 501 E. Middlefield Rd.
- Mailstop MV068
- Mountain View, CA 94043, USA
- Phone: +1 650 937-3825
- EMail: ggood@netscape.com
-
- This Internet Draft expires 19 April, 2000.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Good October 18, 1999 [Page 16]
-\f
\ No newline at end of file
+++ /dev/null
-
- Internet-Draft E. Stokes
- LDAP Extensions WG D. Byrne
- Intended Category: Informational IBM
- Expires: 25 December 1999 B. Blakley
- Dascom
- P. Behera
- Netscape
- 25 June 1999
-
- Access Control Requirements for LDAP
- <draft-ietf-ldapext-acl-reqts-02.txt>
-
- STATUS OF THIS MEMO
-
- This document is an Internet-Draft and is in full
- conformance with all provisions of Section 10 of RFC2026.
-
- Internet-Drafts are working documents of the Internet
- Engineering Task Force (IETF), its areas, and its working
- groups. Note that other groups may also distribute
- working documents as Internet-Drafts. Internet-Drafts are
- draft documents valid for a maximum of six months and may
- be updated, replaced, or obsoleted by other documents at
- any time. It is inappropriate to use Internet- Drafts as
- reference material or to cite them other than as "work in
- progress."
-
- The list of current Internet-Drafts can be accessed at
- http://www.ietf.org/ietf/1id-abstracts.txt
-
- The list of Internet-Draft Shadow Directories can be
- accessed at http://www.ietf.org/shadow.html.
-
- Comments and suggestions on this document are encouraged.
- Comments on this document should be sent to the LDAPEXT
- working group discussion list:
-
- ietf-ldapext@netscape.com
-
- COPYRIGHT NOTICE
- Copyright (C) The Internet Society (1997). All Rights
- Reserved.
-
-
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 1]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- ABSTRACT
-
- This document describes the fundamental requirements of
- an access control list (ACL) model for the Lightweight
- Directory Application Protocol (LDAP) directory service.
- It is intended to be a gathering place for access control
- requirements needed to provide authorized access to and
- interoperability between directories. The RFC 2119
- terminology is used in this document.
-
-
-
- 1. Introduction
-
- The ability to securely access (replicate and distribute)
- directory information throughout the network is necessary
- for successful deployment. LDAP's acceptance as an
- access protocol for directory information is driving the
- need to provide an access control model definition for
- LDAP directory content among servers within an enterprise
- and the Internet. Currently LDAP does not define an
- access control model, but is needed to ensure consistent
- secure access across heterogeneous LDAP implementations.
- The requirements for access control are critical to the
- successful deployment and acceptance of LDAP in the
- market place.
-
- The RFC 2119 terminology is used in this document.
-
-
- 2. Objectives
-
- The major objective is to provide a simple, but secure,
- highly efficient access control model for LDAP while also
- providing the appropriate flexibility to meet the needs
- of both the Internet and enterprise environments and
- policies.
-
- This generally leads to several general requirements that
- are discussed below.
-
-
- 3. Requirements
-
- This section is divided into several areas of
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 2]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- requirements: general, semantics/policy, usability, and
- nested groups (an unresolved issue). The requirements
- are not in any priority order. Examples and explanatory
- text is provided where deemed necessary. Usability is
- perhaps the one set of requirements that is generally
- overlooked, but must be addressed to provide a secure
- system. Usability is a security issue, not just a nice
- design goal and requirement. If it is impossible to set
- and manage a policy for a secure situation that a human
- can understand, then what was set up will probably be
- non-secure. We all need to think of usability as a
- functional security requirement.
-
- 3.1 General
-
- G1. Model SHOULD be general enough to support
- extensibility to add desirable features in the future.
-
- G2. When in doubt, safer is better, especially when
- establishing defaults.
-
- G3. ACL administration SHOULD be part of the LDAP
- protocol. Access control information MUST be an LDAP
- attribute.
-
- G4. Object reuse protection SHOULD be provided and MUST
- NOT inhibit implementation of object reuse. The directory
- SHOULD support policy controlling the re-creation of
- deleted DNs, particularly in cases where they are re-
- created for the purpose of assigning them to a subject
- other than the owner of the deleted DN.
-
- 3.2 Semantics / Policy
-
- S1. Omitted as redundant; see U8.
-
- S2. More specific policies must override less specific
- ones (e.g. individual user entry in ACL SHOULD take
- precedence over group entry) for the evaluation of an
- ACL.
-
- S3. Multiple policies of equal specificity SHOULD be
- combined in some easily-understood way (e.g. union or
- intersection). This is best understood by example.
- Suppose user A belongs to 3 groups and those 3 groups are
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 3]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- listed on the ACL. Also suppose that the permissions for
- each of those groups are not identical. Each group is of
- equal specificity (e.g. each group is listed on the ACL)
- and the policy for granting user A access (given the
- example) SHOULD be combined in some easily understood
- way, such as by intersection or union. For example, an
- intersection policy here may yield a more limited access
- for user A than a union policy.
-
- S4. Newly created directory entries SHOULD be subject to
- a secure default policy.
-
- S5. Access policy SHOULD NOT be expressed in terms of
- attributes which the directory administrator or his
- organization cannot administer (e.g. groups whose
- membership is administered by another organization).
-
- S6. Access policy SHOULD NOT be expressed in terms of
- attributes which are easily forged (e.g. IP addresses).
- There may be valid reasons for enabling access based on
- attributes that are easily forged and the
- behavior/implications of doing that should be documented.
-
- S7. Humans (including administrators) SHOULD NOT be
- required to manage access policy on the basis of
- attributes which are not "human-readable" (e.g. IP
- addresses).
-
- S8. It MUST be possible to deny a subject the right to
- invoke a directory operation. The system SHOULD NOT
- require a specific implementation of denial (e.g.
- explicit denial, implicit denial).
-
- S9. The system MUST be able (semantically) to support
- either default-grant or default-deny semantics (not
- simultaneously).
-
- S10. The system MUST be able to support either union
- semantics or intersection semantics for aggregate
- subjects (not simultaneously).
-
- S11. Absence of policy SHOULD be interpretable as grant
- or deny. Deny takes precedence over grant among entries
- of equal specificity.
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 4]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- S12. ACL policy resolution MUST NOT depend on the order
- of entries in the ACL.
-
- S13. Rights management MUST have no side effects.
- Granting a subject one right to an object MUST NOT
- implicitly grant the same or any other subject a
- different right to the same object. Granting a privilege
- attribute to one subject MUST NOT implicitly grant the
- same privilege attribute to any other subject. Granting
- a privilege attribute to one subject MUST NOT implicitly
- grant a different privilege attribute to the same or any
- other subject. Definition: An ACL's "scope" is defined
- as the set of directory objects governed by the policy it
- defines; this set of objects is a sub-tree of the
- directory. Changing the policy asserted by an ACL (by
- changing one or more of its entries) MUST NOT implicitly
- change the policy governed by an ACL in a different
- scope.
-
- S14. It SHOULD be possible to apply a single policy to
- multiple directory entries, even if those entries are in
- different subtrees. Applying a single policy to multiple
- directory entries SHOULD NOT require creation and storage
- of multiple copies of the policy data. The system SHOULD
- NOT require a specific implementation (e.g. nested
- groups, named ACLs) of support for policy sharing.
-
- 3.3 Usability (Manageability)
-
- U1. When in doubt, simpler is better, both at the
- interface and in the implementation.
-
- U2. Subjects MUST be drawn from the "natural" LDAP
- namespace; they should be DNs.
-
- U3. It SHOULD NOT be possible via ACL administration to
- lock all users, including all administrators, out of the
- directory.
-
- U4. Administrators SHOULD NOT be required to evaluate
- arbitrary Boolean predicates in order to create or
- understand policy.
-
- U5. Administrators SHOULD be able to administer access
- to directories and their attributes based on their
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 5]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- sensitivity, without having to understand the semantics
- of individual schema elements and their attributes (see
- U9).
-
- U6. Management of access to resources in an entire
- subtree SHOULD require only one ACL (at the subtree
- root). Note that this makes access control based
- explicitly on attribute types very hard, unless you
- constrain the types of entries in subtrees. For example,
- another attribute is added to an entry. That attribute
- may fall outside the grouping covered by the ACL and
- hence require additional administration where the desired
- affect is indeed a different ACL. Access control
- information specified in one administrative area MUST NOT
- have jurisdiction in another area. You SHOULD NOT be
- able to control access to the aliased entry in the alias.
- You SHOULD be able to control access to the alias name.
-
- U7. Override of subtree policy MUST be supported on a
- per-directory-entry basis.
-
- U8. Control of access to individual directory entry
- attributes (not just the whole directory entry) MUST be
- supported.
-
- U9. Administrator MUST be able to coarsen access policy
- granularity by grouping attributes with similar access
- sensitivities.
-
- U10. Control of access on a per-user granularity MUST be
- supported.
-
- U11. Administrator MUST be able to aggregate users (for
- example, by assigning them to groups or roles) to
- simplify administration.
-
- U12. It MUST be possible to review "effective access" of
- any user, group, or role to any entry's attributes. This
- aids the administrator in setting the correct policy.
-
- U13. A single administrator SHOULD be able to define
- policy for the entire directory tree. An administrator
- MUST be able to delegate policy administration for
- specific subtrees to other users. This allows for the
- partitioning of the entire directory tree for policy
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 6]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- administration, but still allows a single policy to be
- defined for the entire tree independent of partitioning.
- (Partition in this context means scope of
- administration). An administrator MUST be able to create
- new partitions at any point in the directory tree, and
- MUST be able to merge a superior and subordinate
- partition. An administrator MUST be able to configure
- whether delegated access control information from
- superior partitions is to be accepted or not.
-
- U14. It MUST be possible to authorize users to traverse
- directory structure even if they are not authorized to
- examine or modify some traversed entries; it MUST also be
- possible to prohibit this. The tree structure MUST be
- able to be protected from view if so desired by the
- administrator.
-
- U15. It MUST be possible to create publicly readable
- entries, which may be read even by unauthenticated
- clients.
-
- U16. The model for combining multiple access control
- list entries referring to a single individual MUST be
- easy to understand.
-
- U17. Administrator MUST be able to determine where
- inherited policy information comes from, that is, where
- ACLs are located and which ACLs were applied. Where
- inheritance of ACLs is applied, it must be able to be
- shown how/where that new ACL is derived from.
-
- U18. It SHOULD be possible for the administrator to
- configure the access control system to permit users to
- grant additional access control rights for entries which
- they create.
-
-
- 4. Security Considerations
-
- Access control is a security consideration. This
- documents addresses the requirements.
-
-
-
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 7]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- 5. Glossary
-
- This glossary is intended to aid the novice not versed in
- depth about access control. It contains a list [2] of
- terms and their definitions that are commonly used in
- discussing access control.
-
- Access control - The prevention of use of a resource by
- unidentified and/or unauthorized entities in any other
- that an authorized manner.
-
- Access control list - A set of control attributes. It is
- a list, associated with a security object or a group of
- security objects. The list contains the names of
- security subjects and the type of access that may be
- granted.
-
- Access control policy - A set of rules, part of a
- security policy, by which human users, or their
- representatives, are authenticated and by which access by
- these users to applications and other services and
- security objects is granted or denied.
-
- Access context - The context, in terms of such variables
- as location, time of day, level of security of the
- underlying associations, etc., in which an access to a
- security object is made.
-
- Authorization - The granting of access to a security
- object.
-
- Authorization policy - A set of rules, part of an access
- control policy, by which access by security subjects to
- security objects is granted or denied. An authorization
- policy may be defined in terms of access control lists,
- capabilities, or attributes assigned to security
- subjects, security objects, or both.
-
- Control attributes - Attributes, associated with a
- security object that, when matched against the privilege
- attributes of a security subject, are used to grant or
- deny access to the security object. An access control
- list or list of rights or time of day range are examples
- of control attributes.
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 8]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- Credentials - Data that serve to establish the claimed
- identity of a security subject relative to a given
- security domain.
-
- Privilege attributes - Attributes, associated with a
- security subject that, when matched against control
- attributes of a security object, are used to grant or
- deny access to that subject. Group and role memberships
- are examples of privilege attributes.
-
- Security attributes - A general term covering both
- privilege attributes and control attributes. The use of
- security attributes is defined by a security policy.
-
- Security object - An entity in a passive role to which a
- security policy applies.
-
- Security policy - A general term covering both access
- control policies and authorization policies.
-
- Security subject - An entity in an active role to which a
- security policy applies.
-
-
- 6. References
-
- [1] Steve Kille, Tim Howes, M. Wahl, "Lightweight
- Directory Access Protocol (v3)", RFC 2251, August 1997.
-
- [2] ECMA, "Security in Open Systems: A Security
- Framework" ECMA TR/46, July 1988
-
-
- AUTHOR(S) ADDRESS
-
- Bob Blakley Ellen Stokes
- Dascom IBM
- 5515 Balcones Drive 11400 Burnet Rd
- Austin, TX 78731 Austin, TX 78758
- USA USA
- mail-to: blakley@dascom.com mail-to: stokes@austin.ibm.com
- phone: +1 512 458 4037 ext 5012 phone: +1 512 838 3725
- fax: +1 512 458 2377 fax: +1 512 838 0156
-
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 9]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- Debbie Byrne Prasanta Behera
- IBM Netscape
- 11400 Burnet Rd 501 Ellis Street
- Austin, TX 78758 Mountain View, CA 94043
- USA USA
- mail-to: djbyrne@us.ibm.com mail-to: prasanta@netscape.com
- phone: +1 512 838 1930 phone: +1 650 937 4948
- fax: +1 512 838 8597 fax: +1 650 528-4164
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 10]
-\f
-
-
-
-
- Internet-Draft ACI Requirements 25 June 1999
-
-
-
- 7. Full Copyright Statement
-
- Copyright (C) The Internet Society (1999).á All Rights
- Reserved.
-
- This document and translations of it may be copied and
- furnished to others, and derivative works that comment on or
- otherwise explain it or assist in its implementation may be
- prepared, copied, published and distributed, in whole or in
- part, without restriction of any kind, provided that the
- above copyright notice and this paragraph are included on
- all such copies and derivative works.á However, this
- document itself may not be modified in any way, such as by
- removing the copyright notice or references to the Internet
- Society or other Internet organizations, except as needed
- for the purpose of developing Internet standards in which
- case the procedures for copyrights defined in the Internet
- Standards process must be followed, or as required to
- translate it into languages other than English.
-
- The limited permissions granted above are perpetual and will
- not be revoked by the Internet Society or its successors or
- assigns.
-
- This document and the information contained herein is
- provided on an "AS IS" basis and THE INTERNET SOCIETY AND
- THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL
- WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
- INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Stokes, etal Expires 25 December 1999 [Page 11]
-\f
-
+
Individual Submission to LDAPExt Working Group R. Harrison
Internet Draft Novell, Inc.
-Document: draft-rharrison-ldap-extpartresp-00.txt October, 1999
+Document: draft-rharrison-ldap-extpartresp-01.txt June, 2000
Category: Proposed Standard
protocol without requiring a new revision of the protocol.
The LDAP v3 Extended Operation allows for a single extended response
- to each extended request, but this paradigm may not be efficient
- enough for some directory operations. For instance, the LDAP search
+ to each extended request, but this paradigm may not be sufficient
+ for some directory operations. For instance, the LDAP search
operation is a directory operation that is much more efficient when
multiple partial responses are used to service a single request. The
-
-Harrison Individual Submission û Expires April 14, 2000 1
\f
- LDAP v3 Extended Partial Response October, 1999
+ LDAP v3 Extended Partial Response June, 2000
extended partial response generalizes the current extended operation
definition to give LDAP server implementers the ability to make use
of a single-request-multiple-response paradigm for extended LDAP
- operations that would benefit from it.
+ operations that require it or that would benefit from it.
4. Element of Protocol
The ExtendedPartialResponse is defined as
ExtendedPartialResponse ::= [APPLICATION 25] SEQUENCE {
- responseName [0] LDAPOID,
+ responseName [0] LDAPOID OPTIONAL,
response [1] OCTET STRING OPTIONAL }
An LDAP server responds to an LDAP v3 ExtendedRequest with zero or
Roger Harrison
Novell, Inc.
-
-Harrison Individual Submission û Expires April 14, 2000 2
\f
- LDAP v3 Extended Partial Response October, 1999
+ LDAP v3 Extended Partial Response June, 2000
- 122 E. 1700 S.
+ 1800 S. Novell Place
Provo, UT 84606
+1 801 861 2642
roger_harrison@novell.com
+
+Appendix A - Document Revision History
+
+A.1 draft-rharrison-ldap-extPartResp-00.doc
+
+ Initial revision of draft.
+
+A.2 draft-rharrison-ldap-extPartResp-01.doc
+
+ Changed responseName to be optional to align with [LDAPv3]
+ definition of ExtendedResponse.
+
Full Copyright Statement
"Copyright (C) The Internet Society (date). All Rights Reserved.
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Harrison Individual Submission û Expires April 14, 2000 3
-\f
specified, the program will choose the best mechanism the server knows.
.TP
.B \-Z[Z]
-Request the use of TLS (Transport Layer Security). If you use
+Issue StartTLS (Transport Layer Security) extended operation. If you use
.B \-ZZ\c
-, the command will fail if TLS negotiation does not succeed for some reason.
+, the command will require the operation to be successful.
.SH EXAMPLE
The following command:
.LP
specified, the program will choose the best mechanism the server knows.
.TP
.B \-Z[Z]
-Request the use of TLS (Transport Layer Security). If you use
+Issue StartTLS (Transport Layer Security) extended operation. If you use
.B \-ZZ\c
-, the command will fail if TLS negotiation does not succeed for some reason.
+, the command will require the operation to be successful.
.SH INPUT FORMAT
The contents of \fIfile\fP (or standard input if no \-f flag is given on
the command line) should conform to the format defined in
specified, the program will choose the best mechanism the server knows.
.TP
.B \-Z[Z]
-Request the use of TLS (Transport Layer Security). If you use
+Issue StartTLS (Transport Layer Security) extended operation. If you use
.B \-ZZ\c
-, the command will fail if TLS negotiation does not succeed for some reason.
+, the command will require the operation to be successful.
.SH INPUT FORMAT
If the command-line arguments \fIdn\fP and \fIrdn\fP are given, \fIrdn\fP
will replace the RDN of the entry specified by the DN, \fIdn\fP.
specified, the program will choose the best mechanism the server knows.
.TP
.B \-Z[Z]
-Request the use of TLS (Transport Layer Security). If you use
+Issue StartTLS (Transport Layer Security) extended operation. If you use
.B \-ZZ\c
-, the command will fail if TLS negotiation does not succeed for some reason.
+, the command will require the operation to be successful.
.SH SEE ALSO
.BR ldap_bind (3)
.SH ACKNOWLEDGEMENTS
specified, the program will choose the best mechanism the server knows.
.TP
.B \-Z[Z]
-Request the use of TLS (Transport Layer Security). If you use
+Issue StartTLS (Transport Layer Security) extended operation. If you use
.B \-ZZ\c
-, the command will fail if TLS negotiation does not succeed for some reason.
+, the command will require the operation to be successful.
.SH OUTPUT FORMAT
If one or more entries are found, each entry is written to standard output
in the form:
.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
-ldap - Lightweight Directory Access Protocol package
+ldap - OpenLDAP Lightweight Directory Access Protocol API
.SH SYNOPSIS
.nf
.ft B
.LP
Both synchronous and asynchronous APIs are provided. Also included are
various routines to parse the results returned from these routines.
-These routines are found in the libldap.a library.
+These routines are found in the \-lldap library.
.LP
The basic interaction is as follows. A connection is made to an LDAP
server by calling
.BR ldap_friendly (3)
routines are
used to map from short two letter country codes (or other strings)
-to longer "friendlier" names. The
-.BR ldap_charset (3)
-routines can be used to translate to and from the T.61 character
-set used for many character strings in the LDAP protocol.
+to longer "friendlier" names.
.SH CONNECTIONLESS ACCESS
The
.BR cldap_search_s (3)
--- /dev/null
+.TH SLAPPASSWD 8C "15 June 2000" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 1998-2000 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
+.SH NAME
+slappassword \- OpenLDAP password utility
+.SH SYNOPSIS
+.B SBINDIR/slappasswd
+.B [\-v]
+.B [\-s secret]
+.B [\-h hash]
+.B
+.LP
+.SH DESCRIPTION
+.LP
+.B Slappasswd
+is used to compute a hashed password suitable for use
+as a userPassword value
+.BR slapd.conf (5)
+.BR rootpw .
+.SH OPTIONS
+.TP
+.B \-v
+enable verbose mode.
+.TP
+.BI \-s " secret"
+The secret to hash. If not provided, the user will be prompted
+for the secret to hash.
+.TP
+.BI \-h " hash"
+The hash algorithm to use. Algorithms supported include
+.IR {CRYPT} ,
+.IR {MD5} ,
+.IR {SMD5} ,
+.IR {SSHA} ", and"
+.IR {SHA} .
+The default is
+.IR {SSHA} .
+.SH LIMITATIONS
+The practice storing hashed passwords in userPassword
+violates Standard Track schema and may hinder
+interoperability.
+.SH "SECURITY CONSIDERATIONS"
+Use of hashed passwords does not protect passwords during
+protocol transfer. TLS or other eavesdropping protections
+should be inplace before using LDAP simple bind. The
+hashed password values should be protected as if they
+were clear text passwords.
+.SH "SEE ALSO"
+.BR ldapmodify (3),
+.BR slapd (8)
+.SH ACKNOWLEDGEMENTS
+.B OpenLDAP
+is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
+.B OpenLDAP
+is derived from University of Michigan LDAP 3.3 Release.
--- /dev/null
+This is an index of RFC contained in this directory:
+
+STD Standard
+DS Draft Standard
+PS Proposed Standard
+
+I Information
+E Experimental
+
+rfc1274.txt COSINE and Internet X.500 Schema (PS)
+rfc1275.txt X.500 Replication Requirements (I)
+rfc1279.txt X.500 and Domains (E)
+rfc1308.txt Executive Intro to Directory Services - X.500 (FYI13)
+rfc1309.txt Technical Overview of Directory Services - X.500 (FYI14)
+rfc1430.txt Plan for Deploying an Internet X.500 Directory Service (I)
+rfc1617.txt Naming and Structuring Guidelines for X.500 Directory Pilots (I)
+rfc1777.txt Lightweight Directory Access Protocol (DS)
+rfc1778.txt LDAP String Representation of Attribute Types (DS)
+rfc1779.txt LDAP String Representation of DNs (DS)
+rfc1781.txt Using the OSI Directory to Achieve User Friendly Naming (PS)
+rfc1798.txt Connection-less LDAP (PS)
+rfc1823.txt LDAP C API (I)
+rfc1959.txt LDAP URL Format (PS)
+rfc1960.txt LDAP String Representation of Search Filters (DS)
+rfc2079.txt X.500 Attribute Type and an Object Class to Hold URIs (PS)
+rfc2119.txt Key words (BCP14)
+rfc2164.txt X.500/LDAP MIXER address mapping (PS)
+rfc2218.txt Common Schema for the Internet White Pages Service (PS)
+rfc2222.txt Simple Authentication and Security Layer (PS)
+rfc2247.txt Using Domains in LDAP DNs (PS)
+rfc2251.txt LDAPv3 Protocol (PS)
+rfc2252.txt LDAPv3 Attribute Types (PS)
+rfc2253.txt LDAPv3 Disinguished Name (PS)
+rfc2254.txt LDAPv3 Search Filters (PS)
+rfc2255.txt LDAPv3 URI (PS)
+rfc2256.txt X.500(96) Schema for LDAPv3 (PS)
+rfc2279.txt UTF-8 (DS)
+rfc2293.txt Tables and Subtrees in the X.500 Directory (PS)
+rfc2294.txt O/R Address hierarchy in the X.500 DIT (PS)
+rfc2307.txt LDAP Network Information Services Schema (I)
+rfc2377.txt LDAP Naming Plan (I)
+rfc2559.txt Internet X.509 PKI Operational Protocols - LDAPv2 (PS)
+rfc2587.txt Internet X.509 PKI LDAPv2 Schema (PS)
+rfc2589.txt LDAPv3: Dynamic Directory Services Extensions (PS)
+rfc2596.txt Use of Language Codes in LDAP (PS)
+rfc2649.txt LDAPv3 Operational Signatures (E)
+rfc2657.txt LDAPv2 Client vs. the Index Mesh (E)
+rfc2696.txt LDAP Simple Paged Result Control (PS)
+rfc2713.txt LDAP Java schema (I)
+rfc2714.txt LDAP COBRA schema (I)
+rfc2798.txt LDAP inetOrgPerson schema (I)
+rfc2829.txt LDAPv3/Authentication Methods (PS)
+rfc2830.txt LDAPv3/StartTLS (PS)
+rfc2831.txt SASL/DIGEST-MD5 (PS)
+rfc2849.txt LDIFv1 (PS)
--- /dev/null
+
+
+
+
+
+
+Network Working Group G. Good
+Request for Comments: 2849 iPlanet e-commerce Solutions
+Category: Standards Track June 2000
+
+
+ The LDAP Data Interchange Format (LDIF) - Technical Specification
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+Abstract
+
+ This document describes a file format suitable for describing
+ directory information or modifications made to directory information.
+ The file format, known as LDIF, for LDAP Data Interchange Format, is
+ typically used to import and export directory information between
+ LDAP-based directory servers, or to describe a set of changes which
+ are to be applied to a directory.
+
+Background and Intended Usage
+
+ There are a number of situations where a common interchange format is
+ desirable. For example, one might wish to export a copy of the
+ contents of a directory server to a file, move that file to a
+ different machine, and import the contents into a second directory
+ server.
+
+ Additionally, by using a well-defined interchange format, development
+ of data import tools from legacy systems is facilitated. A fairly
+ simple set of tools written in awk or perl can, for example, convert
+ a database of personnel information into an LDIF file. This file can
+ then be imported into a directory server, regardless of the internal
+ database representation the target directory server uses.
+
+ The LDIF format was originally developed and used in the University
+ of Michigan LDAP implementation. The first use of LDIF was in
+ describing directory entries. Later, the format was expanded to
+ allow representation of changes to directory entries.
+
+
+
+
+Good Standards Track [Page 1]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+ Relationship to the application/directory MIME content-type:
+
+ The application/directory MIME content-type [1] is a general
+ framework and format for conveying directory information, and is
+ independent of any particular directory service. The LDIF format is
+ a simpler format which is perhaps easier to create, and may also be
+ used, as noted, to describe a set of changes to be applied to a
+ directory.
+
+ The key words "MUST", "MUST NOT", "MAY", "SHOULD", and "SHOULD NOT"
+ used in this document are to be interpreted as described in [7].
+
+Definition of the LDAP Data Interchange Format
+
+ The LDIF format is used to convey directory information, or a
+ description of a set of changes made to directory entries. An LDIF
+ file consists of a series of records separated by line separators. A
+ record consists of a sequence of lines describing a directory entry,
+ or a sequence of lines describing a set of changes to a directory
+ entry. An LDIF file specifies a set of directory entries, or a set
+ of changes to be applied to directory entries, but not both.
+
+ There is a one-to-one correlation between LDAP operations that modify
+ the directory (add, delete, modify, and modrdn), and the types of
+ changerecords described below ("add", "delete", "modify", and
+ "modrdn" or "moddn"). This correspondence is intentional, and
+ permits a straightforward translation from LDIF changerecords to
+ protocol operations.
+
+Formal Syntax Definition of LDIF
+
+ The following definition uses the augmented Backus-Naur Form
+ specified in RFC 2234 [2].
+
+ldif-file = ldif-content / ldif-changes
+
+ldif-content = version-spec 1*(1*SEP ldif-attrval-record)
+
+ldif-changes = version-spec 1*(1*SEP ldif-change-record)
+
+ldif-attrval-record = dn-spec SEP 1*attrval-spec
+
+ldif-change-record = dn-spec SEP *control changerecord
+
+version-spec = "version:" FILL version-number
+
+
+
+
+
+
+Good Standards Track [Page 2]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+version-number = 1*DIGIT
+ ; version-number MUST be "1" for the
+ ; LDIF format described in this document.
+
+dn-spec = "dn:" (FILL distinguishedName /
+ ":" FILL base64-distinguishedName)
+
+distinguishedName = SAFE-STRING
+ ; a distinguished name, as defined in [3]
+
+base64-distinguishedName = BASE64-UTF8-STRING
+ ; a distinguishedName which has been base64
+ ; encoded (see note 10, below)
+
+rdn = SAFE-STRING
+ ; a relative distinguished name, defined as
+ ; <name-component> in [3]
+
+base64-rdn = BASE64-UTF8-STRING
+ ; an rdn which has been base64 encoded (see
+ ; note 10, below)
+
+control = "control:" FILL ldap-oid ; controlType
+ 0*1(1*SPACE ("true" / "false")) ; criticality
+ 0*1(value-spec) ; controlValue
+ SEP
+ ; (See note 9, below)
+
+ldap-oid = 1*DIGIT 0*1("." 1*DIGIT)
+ ; An LDAPOID, as defined in [4]
+
+attrval-spec = AttributeDescription value-spec SEP
+
+value-spec = ":" ( FILL 0*1(SAFE-STRING) /
+ ":" FILL (BASE64-STRING) /
+ "<" FILL url)
+ ; See notes 7 and 8, below
+
+url = <a Uniform Resource Locator,
+ as defined in [6]>
+ ; (See Note 6, below)
+
+AttributeDescription = AttributeType [";" options]
+ ; Definition taken from [4]
+
+AttributeType = ldap-oid / (ALPHA *(attr-type-chars))
+
+options = option / (option ";" options)
+
+
+
+Good Standards Track [Page 3]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+option = 1*opt-char
+
+attr-type-chars = ALPHA / DIGIT / "-"
+
+opt-char = attr-type-chars
+
+changerecord = "changetype:" FILL
+ (change-add / change-delete /
+ change-modify / change-moddn)
+
+change-add = "add" SEP 1*attrval-spec
+
+change-delete = "delete" SEP
+
+change-moddn = ("modrdn" / "moddn") SEP
+ "newrdn:" ( FILL rdn /
+ ":" FILL base64-rdn) SEP
+ "deleteoldrdn:" FILL ("0" / "1") SEP
+ 0*1("newsuperior:"
+ ( FILL distinguishedName /
+ ":" FILL base64-distinguishedName) SEP)
+
+change-modify = "modify" SEP *mod-spec
+
+mod-spec = ("add:" / "delete:" / "replace:")
+ FILL AttributeDescription SEP
+ *attrval-spec
+ "-" SEP
+
+SPACE = %x20
+ ; ASCII SP, space
+
+FILL = *SPACE
+
+SEP = (CR LF / LF)
+
+CR = %x0D
+ ; ASCII CR, carriage return
+
+LF = %x0A
+ ; ASCII LF, line feed
+
+ALPHA = %x41-5A / %x61-7A
+ ; A-Z / a-z
+
+DIGIT = %x30-39
+ ; 0-9
+
+
+
+
+Good Standards Track [Page 4]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+UTF8-1 = %x80-BF
+
+UTF8-2 = %xC0-DF UTF8-1
+
+UTF8-3 = %xE0-EF 2UTF8-1
+
+UTF8-4 = %xF0-F7 3UTF8-1
+
+UTF8-5 = %xF8-FB 4UTF8-1
+
+UTF8-6 = %xFC-FD 5UTF8-1
+
+SAFE-CHAR = %x01-09 / %x0B-0C / %x0E-7F
+ ; any value <= 127 decimal except NUL, LF,
+ ; and CR
+
+SAFE-INIT-CHAR = %x01-09 / %x0B-0C / %x0E-1F /
+ %x21-39 / %x3B / %x3D-7F
+ ; any value <= 127 except NUL, LF, CR,
+ ; SPACE, colon (":", ASCII 58 decimal)
+ ; and less-than ("<" , ASCII 60 decimal)
+
+SAFE-STRING = [SAFE-INIT-CHAR *SAFE-CHAR]
+
+UTF8-CHAR = SAFE-CHAR / UTF8-2 / UTF8-3 /
+ UTF8-4 / UTF8-5 / UTF8-6
+
+UTF8-STRING = *UTF8-CHAR
+
+BASE64-UTF8-STRING = BASE64-STRING
+ ; MUST be the base64 encoding of a
+ ; UTF8-STRING
+
+BASE64-CHAR = %x2B / %x2F / %x30-39 / %x3D / %x41-5A /
+ %x61-7A
+ ; +, /, 0-9, =, A-Z, and a-z
+ ; as specified in [5]
+
+BASE64-STRING = [*(BASE64-CHAR)]
+
+
+ Notes on LDIF Syntax
+
+ 1) For the LDIF format described in this document, the version
+ number MUST be "1". If the version number is absent,
+ implementations MAY choose to interpret the contents as an
+ older LDIF file format, supported by the University of
+ Michigan ldap-3.3 implementation [8].
+
+
+
+Good Standards Track [Page 5]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+ 2) Any non-empty line, including comment lines, in an LDIF file
+ MAY be folded by inserting a line separator (SEP) and a SPACE.
+ Folding MUST NOT occur before the first character of the line.
+ In other words, folding a line into two lines, the first of
+ which is empty, is not permitted. Any line that begins with a
+ single space MUST be treated as a continuation of the previous
+ (non-empty) line. When joining folded lines, exactly one space
+ character at the beginning of each continued line must be
+ discarded. Implementations SHOULD NOT fold lines in the middle
+ of a multi-byte UTF-8 character.
+
+ 3) Any line that begins with a pound-sign ("#", ASCII 35) is a
+ comment line, and MUST be ignored when parsing an LDIF file.
+
+ 4) Any dn or rdn that contains characters other than those
+ defined as "SAFE-UTF8-CHAR", or begins with a character other
+ than those defined as "SAFE-INIT-UTF8-CHAR", above, MUST be
+ base-64 encoded. Other values MAY be base-64 encoded. Any
+ value that contains characters other than those defined as
+ "SAFE-CHAR", or begins with a character other than those
+ defined as "SAFE-INIT-CHAR", above, MUST be base-64 encoded.
+ Other values MAY be base-64 encoded.
+
+ 5) When a zero-length attribute value is to be included directly
+ in an LDIF file, it MUST be represented as
+ AttributeDescription ":" FILL SEP. For example, "seeAlso:"
+ followed by a newline represents a zero-length "seeAlso"
+ attribute value. It is also permissible for the value
+ referred to by a URL to be of zero length.
+
+ 6) When a URL is specified in an attrval-spec, the following
+ conventions apply:
+
+ a) Implementations SHOULD support the file:// URL format. The
+ contents of the referenced file are to be included verbatim
+ in the interpreted output of the LDIF file.
+ b) Implementations MAY support other URL formats. The
+ semantics associated with each supported URL will be
+ documented in an associated Applicability Statement.
+
+ 7) Distinguished names, relative distinguished names, and
+ attribute values of DirectoryString syntax MUST be valid UTF-8
+ strings. Implementations that read LDIF MAY interpret files
+ in which these entities are stored in some other character set
+ encoding, but implementations MUST NOT generate LDIF content
+ which does not contain valid UTF-8 data.
+
+
+
+
+
+Good Standards Track [Page 6]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+ 8) Values or distinguished names that end with SPACE SHOULD be
+ base-64 encoded.
+
+ 9) When controls are included in an LDIF file, implementations
+ MAY choose to ignore some or all of them. This may be
+ necessary if the changes described in the LDIF file are being
+ sent on an LDAPv2 connection (LDAPv2 does not support
+ controls), or the particular controls are not supported by the
+ remote server. If the criticality of a control is "true", then
+ the implementation MUST either include the control, or MUST
+ NOT send the operation to a remote server.
+
+ 10) When an attrval-spec, distinguishedName, or rdn is base64-
+ encoded, the encoding rules specified in [5] are used with the
+ following exceptions: a) The requirement that base64 output
+ streams must be represented as lines of no more than 76
+ characters is removed. Lines in LDIF files may only be folded
+ according to the folding rules described in note 2, above. b)
+ Base64 strings in [5] may contain characters other than those
+ defined in BASE64-CHAR, and are ignored. LDIF does not permit
+ any extraneous characters, other than those used for line
+ folding.
+
+Examples of LDAP Data Interchange Format
+
+Example 1: An simple LDAP file with two entries
+
+version: 1
+dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+cn: Barbara Jensen
+cn: Barbara J Jensen
+cn: Babs Jensen
+sn: Jensen
+uid: bjensen
+telephonenumber: +1 408 555 1212
+description: A big sailing fan.
+
+dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+cn: Bjorn Jensen
+sn: Jensen
+telephonenumber: +1 408 555 1212
+
+
+
+
+Good Standards Track [Page 7]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+Example 2: A file containing an entry with a folded attribute value
+
+version: 1
+dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
+objectclass:top
+objectclass:person
+objectclass:organizationalPerson
+cn:Barbara Jensen
+cn:Barbara J Jensen
+cn:Babs Jensen
+sn:Jensen
+uid:bjensen
+telephonenumber:+1 408 555 1212
+description:Babs is a big sailing fan, and travels extensively in sea
+ rch of perfect sailing conditions.
+title:Product Manager, Rod and Reel Division
+
+Example 3: A file containing a base-64-encoded value
+
+version: 1
+dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+cn: Gern Jensen
+cn: Gern O Jensen
+sn: Jensen
+uid: gernj
+telephonenumber: +1 408 555 1212
+description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl
+IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG
+VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg
+b3V0IG1vcmUu
+
+Example 4: A file containing an entries with UTF-8-encoded attribute
+values, including language tags. Comments indicate the contents
+of UTF-8-encoded attributes and distinguished names.
+
+version: 1
+dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
+# dn:: ou=<JapaneseOU>,o=Airius
+objectclass: top
+objectclass: organizationalUnit
+ou:: 5Za25qWt6YOo
+# ou:: <JapaneseOU>
+ou;lang-ja:: 5Za25qWt6YOo
+# ou;lang-ja:: <JapaneseOU>
+ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
+
+
+
+Good Standards Track [Page 8]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+# ou;lang-ja:: <JapaneseOU_in_phonetic_representation>
+ou;lang-en: Sales
+description: Japanese office
+
+dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
+# dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius
+userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+uid: rogasawara
+mail: rogasawara@airius.co.jp
+givenname;lang-ja:: 44Ot44OJ44OL44O8
+# givenname;lang-ja:: <JapaneseGivenname>
+sn;lang-ja:: 5bCP56yg5Y6f
+# sn;lang-ja:: <JapaneseSn>
+cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
+# cn;lang-ja:: <JapaneseCn>
+title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
+# title;lang-ja:: <JapaneseTitle>
+preferredlanguage: ja
+givenname:: 44Ot44OJ44OL44O8
+# givenname:: <JapaneseGivenname>
+sn:: 5bCP56yg5Y6f
+# sn:: <JapaneseSn>
+cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
+# cn:: <JapaneseCn>
+title:: 5Za25qWt6YOoIOmDqOmVtw==
+# title:: <JapaneseTitle>
+givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
+# givenname;lang-ja;phonetic::
+<JapaneseGivenname_in_phonetic_representation_kana>
+sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
+# sn;lang-ja;phonetic:: <JapaneseSn_in_phonetic_representation_kana>
+cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
+# cn;lang-ja;phonetic:: <JapaneseCn_in_phonetic_representation_kana>
+title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
+# title;lang-ja;phonetic::
+# <JapaneseTitle_in_phonetic_representation_kana>
+givenname;lang-en: Rodney
+sn;lang-en: Ogasawara
+cn;lang-en: Rodney Ogasawara
+title;lang-en: Sales, Director
+
+
+
+
+
+
+
+Good Standards Track [Page 9]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+Example 5: A file containing a reference to an external file
+
+version: 1
+dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+cn: Horatio Jensen
+
+cn: Horatio N Jensen
+sn: Jensen
+uid: hjensen
+telephonenumber: +1 408 555 1212
+jpegphoto:< file:///usr/local/directory/photos/hjensen.jpg
+
+Example 6: A file containing a series of change records and comments
+
+version: 1
+# Add a new entry
+dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
+changetype: add
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+cn: Fiona Jensen
+sn: Jensen
+uid: fiona
+telephonenumber: +1 408 555 1212
+jpegphoto:< file:///usr/local/directory/photos/fiona.jpg
+
+# Delete an existing entry
+dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
+changetype: delete
+
+# Modify an entry's relative distinguished name
+dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
+changetype: modrdn
+newrdn: cn=Paula Jensen
+deleteoldrdn: 1
+
+# Rename an entry and move all of its children to a new location in
+# the directory tree (only implemented by LDAPv3 servers).
+dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
+changetype: modrdn
+newrdn: ou=Product Development Accountants
+deleteoldrdn: 0
+newsuperior: ou=Accounting, dc=airius, dc=com
+
+
+
+
+Good Standards Track [Page 10]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+# Modify an entry: add an additional value to the postaladdress
+# attribute, completely delete the description attribute, replace
+# the telephonenumber attribute with two values, and delete a specific
+# value from the facsimiletelephonenumber attribute
+dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
+changetype: modify
+add: postaladdress
+postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
+-
+
+delete: description
+-
+replace: telephonenumber
+telephonenumber: +1 408 555 1234
+telephonenumber: +1 408 555 5678
+-
+delete: facsimiletelephonenumber
+facsimiletelephonenumber: +1 408 555 9876
+-
+
+# Modify an entry: replace the postaladdress attribute with an empty
+# set of values (which will cause the attribute to be removed), and
+# delete the entire description attribute. Note that the first will
+# always succeed, while the second will only succeed if at least
+# one value for the description attribute is present.
+dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com
+changetype: modify
+replace: postaladdress
+-
+delete: description
+-
+
+Example 7: An LDIF file containing a change record with a control
+version: 1
+# Delete an entry. The operation will attach the LDAPv3
+# Tree Delete Control defined in [9]. The criticality
+# field is "true" and the controlValue field is
+# absent, as required by [9].
+dn: ou=Product Development, dc=airius, dc=com
+control: 1.2.840.113556.1.4.805 true
+changetype: delete
+
+
+
+
+
+
+
+
+
+
+Good Standards Track [Page 11]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+Security Considerations
+
+ Given typical directory applications, an LDIF file is likely to
+ contain sensitive personal data. Appropriate measures should be
+ taken to protect the privacy of those persons whose data is contained
+ in an LDIF file.
+
+ Since ":<" directives can cause external content to be included when
+ processing an LDIF file, one should be cautious of accepting LDIF
+ files from external sources. A "trojan" LDIF file could name a file
+ with sensitive contents and cause it to be included in a directory
+ entry, which a hostile entity could read via LDAP.
+
+ LDIF does not provide any method for carrying authentication
+ information with an LDIF file. Users of LDIF files must take care to
+ verify the integrity of an LDIF file received from an external
+ source.
+
+Acknowledgments
+
+ The LDAP Interchange Format was developed as part of the University
+ of Michigan LDAP reference implementation, and was developed by Tim
+ Howes, Mark Smith, and Gordon Good. It is based in part upon work
+ supported by the National Science Foundation under Grant No. NCR-
+ 9416667.
+
+ Members of the IETF LDAP Extensions Working group provided many
+ helpful suggestions. In particular, Hallvard B. Furuseth of the
+ University of Oslo made many significant contributions to this
+ document, including a thorough review and rewrite of the BNF.
+
+References
+
+ [1] Howes, T. and M. Smith, "A MIME Content-Type for Directory
+ Information", RFC 2425, September 1998.
+
+ [2] Crocker, D., and P. Overell, "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 2234, November 1997.
+
+ [3] Wahl, M., Kille, S. and T. Howes, "A String Representation of
+ Distinguished Names", RFC 2253, December 1997.
+
+ [4] Wahl, M., Howes, T. and S. Kille, "Lightweight Directory Access
+ Protocol (v3)", RFC 2251, July 1997.
+
+ [5] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+ Extensions (MIME) Part One: Format of Internet Message Bodies",
+ RFC 2045, November 1996.
+
+
+
+Good Standards Track [Page 12]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+ [6] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform
+ Resource Locators (URL)", RFC 1738, December 1994.
+
+ [7] Bradner, S., "Key Words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [8] The SLAPD and SLURPD Administrators Guide. University of
+ Michigan, April 1996. <URL:
+ http://www.umich.edu/~dirsvcs/ldap/doc/guides/slapd/toc.html>
+
+ [9] M. P. Armijo, "Tree Delete Control", Work in Progress.
+
+Author's Address
+
+ Gordon Good
+ iPlanet e-commerce Solutions
+ 150 Network Circle
+ Mailstop USCA17-201
+ Santa Clara, CA 95054, USA
+
+ Phone: +1 408 276 4351
+ EMail: ggood@netscape.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Good Standards Track [Page 13]
+\f
+RFC 2849 LDAP Data Interchange Format June 2000
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph are
+ included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is currently provided by the
+ Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Good Standards Track [Page 14]
+\f
#define SLAPD_LDBM_MIN_MAXIDS (8192-4)
/* the following DNs must be normalized! */
- /* dn of the special "schema" entry */
-#define SLAPD_SCHEMA_DN "cn=Schema"
+ /* dn of the default subschema subentry */
+#define SLAPD_SCHEMA_DN "cn=Subschema"
#if 0
- /* dn of the special "monitor" entry */
+ /* dn of the default "monitor" subentry */
#define SLAPD_MONITOR_DN "cn=Monitor"
- /* dn of the special "config" entry */
+ /* dn of the default "config" subentry */
#define SLAPD_CONFIG_DN "cn=Config"
#endif
if ( sb->sb_debug ) {
ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
- "ber_flush: %ld bytes to sd %ld%s\n", towrite,
- (long) sb->sb_fd, ber->ber_rwptr != ber->ber_buf ?
- " (re-flush)" : "" );
+ "ber_flush: %ld bytes to sd %ld%s\n",
+ towrite, (long) sb->sb_fd,
+ ber->ber_rwptr != ber->ber_buf ? " (re-flush)" : "" );
ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
ber->ber_rwptr, towrite );
}
}
do {
/* reading the tag... */
- if (ber_int_sb_read( sb, ber->ber_rwptr, 1)<=0)
+ if (ber_int_sb_read( sb, ber->ber_rwptr, 1)<=0) {
return LBER_DEFAULT;
+ }
+
if (! (ber->ber_rwptr[0] & LBER_MORE_TAG_MASK) ) {
ber->ber_tag>>=sizeof(ber->ber_tag) -
((char *) &ber->ber_tag - ber->ber_rwptr);
goto get_lenbyte;
}
} while( PTR_IN_VAR(ber->ber_rwptr, ber->ber_tag ));
+
errno = ERANGE; /* this is a serious error. */
return LBER_DEFAULT;
}
for ( i = 0; attrs[i] != NULL; i++ ) {
if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
rc = ber_printf( ber, "{s[V]}", attrs[i]->mod_type,
- attrs[i]->mod_values );
+ attrs[i]->mod_bvalues );
} else {
rc = ber_printf( ber, "{s[v]}", attrs[i]->mod_type,
attrs[i]->mod_values );
}
static ber_socket_t
-ldap_pvt_socket(LDAP *ld)
+ldap_pvt_socket(LDAP *ld, int family)
{
- ber_socket_t s = socket(AF_INET, SOCK_STREAM, 0);
+ ber_socket_t s = socket(family, SOCK_STREAM, 0);
osip_debug(ld, "ldap_new_socket: %d\n",s,0,0);
return ( s );
}
#undef TRACE
static int
-ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_in *sin, int async)
+ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr *sin, socklen_t addrlen, int async)
{
struct timeval tv, *opt_tv=NULL;
fd_set wfds, *z=NULL;
if ( ldap_pvt_ndelay_on(ld, s) == -1 )
return ( -1 );
- if ( connect(s, (struct sockaddr *) sin, sizeof(struct sockaddr_in)) == 0 )
+ if ( connect(s, sin, addrlen) == 0 )
{
if ( ldap_pvt_ndelay_off(ld, s) == -1 )
return ( -1 );
osip_debug(ld, "ldap_connect_to_host\n",0,0,0);
if (host != NULL) {
+#ifdef HAVE_GETADDRINFO
+ char serv[7];
+ struct addrinfo hints, *res, *sai;
+
+ memset( &hints, '\0', sizeof(hints) );
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ snprintf(serv, sizeof serv, "%d", ntohs(port));
+ if ( getaddrinfo(host, serv, &hints, &res) ) {
+ osip_debug(ld, "ldap_connect_to_host:getaddrinfo failed\n",0,0,0);
+ return -1;
+ }
+ sai = res;
+ rc = -1;
+ do {
+ s = ldap_pvt_socket( ld, sai->ai_family );
+ if ( s == -1 ) {
+ continue;
+ }
+
+ switch (sai->ai_family) {
+#ifdef LDAP_PF_INET6
+ case AF_INET6: {
+ char addr[INET6_ADDRSTRLEN];
+ inet_ntop( AF_INET6,
+ &((struct sockaddr_in6 *)sai->ai_addr)->sin6_addr,
+ addr, sizeof addr);
+ osip_debug(ld, "ldap_connect_to_host: Trying %s %s\n",
+ addr, serv, 0);
+ } break;
+#endif
+ case AF_INET: {
+ char addr[INET_ADDRSTRLEN];
+ inet_ntop( AF_INET,
+ &((struct sockaddr_in *)sai->ai_addr)->sin_addr,
+ addr, sizeof addr);
+ osip_debug(ld, "ldap_connect_to_host: Trying %s:%s\n",
+ addr, serv, 0);
+ } break;
+ }
+ rc = ldap_pvt_connect(ld, s, sai->ai_addr, sai->ai_addrlen, async);
+ if ( (rc == 0) || (rc == -2) ) {
+ ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
+ break;
+ }
+ ldap_pvt_close_socket(ld, s);
+ } while ((sai = sai->ai_next) != NULL);
+ freeaddrinfo(res);
+ return rc;
+#else
if (! inet_aton( host, &in) ) {
rc = ldap_pvt_gethostbyname_a(host, &he_buf, &ha_buf,
&hp, &local_h_errno);
- if ( rc < 0 )
- ; /*XXX NO MEMORY? */
-
if ( (rc < 0) || (hp == NULL) ) {
#ifdef HAVE_WINSOCK
ldap_pvt_set_errno( WSAGetLastError() );
use_hp = 1;
}
address = in.s_addr;
+#endif
}
rc = s = -1;
for ( i = 0; !use_hp || (hp->h_addr_list[i] != 0); ++i, rc = -1 ) {
- if ( (s = ldap_pvt_socket( ld )) == -1 )
+ s = ldap_pvt_socket( ld, AF_INET );
+ if ( s == -1 ) {
/* use_hp ? continue : break; */
break;
+ }
if ( ldap_pvt_prepare_socket(ld, s) == -1 ) {
ldap_pvt_close_socket(ld, s);
osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n",
inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),0);
- rc = ldap_pvt_connect(ld, s, &sin, async);
+ rc = ldap_pvt_connect(ld, s, (struct sockaddr *)&sin, sizeof(struct sockaddr_in), async);
if ( (rc == 0) || (rc == -2) ) {
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
{
struct hostent *hp;
socklen_t len;
- struct sockaddr_in sin;
+ struct sockaddr sa;
+ char *addr;
/* buffers for gethostbyaddr_r */
struct hostent he_buf;
ber_socket_t sd;
#define DO_RETURN(x) if (ha_buf) LDAP_FREE(ha_buf); return (x);
- (void)memset( (char *)&sin, '\0', sizeof( struct sockaddr_in ));
- len = sizeof( sin );
+ (void)memset( (char *)&sa, '\0', sizeof( struct sockaddr ));
+ len = sizeof( sa );
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
- if ( getpeername( sd, (struct sockaddr *)&sin, &len ) == -1 ) {
+ if ( getpeername( sd, (struct sockaddr *)&sa, &len ) == -1 ) {
return( NULL );
}
* this is necessary for kerberos to work right, since the official
* hostname is used as the kerberos instance.
*/
- if ((ldap_pvt_gethostbyaddr_a( (char *) &sin.sin_addr,
- sizeof( sin.sin_addr ),
- AF_INET, &he_buf, &ha_buf,
+
+ switch (sa.sa_family) {
+#ifdef LDAP_PF_INET6
+ case AF_INET6:
+ addr = (char *) &((struct sockaddr_in6 *)&sa)->sin6_addr;
+ len = sizeof( struct in6_addr );
+ break;
+#endif
+ case AF_INET:
+ addr = (char *) &((struct sockaddr_in *)&sa)->sin_addr;
+ len = sizeof( struct in_addr );
+ break;
+ default:
+ return( NULL );
+ break;
+ }
+ if ((ldap_pvt_gethostbyaddr_a( addr, len,
+ sa.sa_family, &he_buf, &ha_buf,
&hp,&local_h_errno ) ==0 ) && (hp != NULL) )
{
if ( hp->h_name != NULL ) {
}
}
}
+
+ if( lr->lr_res_matched != NULL ) {
+ LDAP_FREE( lr->lr_res_matched );
+ lr->lr_res_matched = NULL;
+ }
+ if( lr->lr_res_error != NULL ) {
+ LDAP_FREE( lr->lr_res_error );
+ lr->lr_res_error = NULL;
+ }
}
}
}
ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
/* active threads? */
if( rw->ltrw_r_active > 0 || rw->ltrw_w_active > 0) {
ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
if( rw->ltrw_w_active > 0 ) {
/* writer is active */
} while( rw->ltrw_w_active > 0 );
rw->ltrw_r_wait--;
+ assert( rw->ltrw_r_wait >= 0 );
}
rw->ltrw_r_active++;
ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
if( rw->ltrw_w_active > 0) {
ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
return LDAP_PVT_THREAD_EBUSY;
rw->ltrw_r_active--;
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
if (rw->ltrw_r_active == 0 && rw->ltrw_w_wait > 0 ) {
ldap_pvt_thread_cond_signal( &rw->ltrw_write );
}
ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
if ( rw->ltrw_w_active > 0 || rw->ltrw_r_active > 0 ) {
rw->ltrw_w_wait++;
} while ( rw->ltrw_w_active > 0 || rw->ltrw_r_active > 0 );
rw->ltrw_w_wait--;
+ assert( rw->ltrw_w_wait >= 0 );
}
rw->ltrw_w_active++;
ldap_pvt_thread_mutex_lock( &rw->ltrw_mutex );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
if ( rw->ltrw_w_active > 0 || rw->ltrw_r_active > 0 ) {
ldap_pvt_thread_mutex_unlock( &rw->ltrw_mutex );
return LDAP_PVT_THREAD_EBUSY;
rw->ltrw_w_active--;
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
+
if (rw->ltrw_r_wait > 0) {
ldap_pvt_thread_cond_broadcast( &rw->ltrw_read );
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
return( rw->ltrw_r_active );
}
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
return( rw->ltrw_w_active );
}
assert( rw != NULL );
assert( rw->ltrw_valid == LDAP_PVT_THREAD_RDWR_VALID );
+ assert( rw->ltrw_w_active >= 0 );
+ assert( rw->ltrw_w_wait >= 0 );
+ assert( rw->ltrw_r_active >= 0 );
+ assert( rw->ltrw_r_wait >= 0 );
return(ldap_pvt_thread_rdwr_readers(rw) +
ldap_pvt_thread_rdwr_writers(rw));
}
+DWORD
+svc_installed (LPTSTR lpszServiceName, LPTSTR lpszBinaryPathName)
+{
+ char buf[256];
+ HKEY key;
+ DWORD rc;
+ DWORD type;
+ long len;
+
+ strcpy(buf, TEXT("SYSTEM\\CurrentControlSet\\Services\\"));
+ strcat(buf, lpszServiceName);
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, buf, 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS)
+ return(-1);
+
+ rc = 0;
+ if (lpszBinaryPathName) {
+ len = sizeof(buf);
+ if (RegQueryValueEx(key, "ImagePath", NULL, &type, buf, &len) == ERROR_SUCCESS) {
+ if (strcmp(lpszBinaryPathName, buf))
+ rc = -1;
+ }
+ }
+ RegCloseKey(key);
+ return(rc);
+}
+
+
+DWORD
+svc_running (LPTSTR lpszServiceName)
+{
+ SC_HANDLE service;
+ SC_HANDLE scm;
+ DWORD rc;
+ SERVICE_STATUS ss;
+
+ if (!(scm = OpenSCManager(NULL, NULL, GENERIC_READ)))
+ return(GetLastError());
+
+ rc = 1;
+ service = OpenService(scm, lpszServiceName, SERVICE_QUERY_STATUS);
+ if (service) {
+ if (!QueryServiceStatus(service, &ss))
+ rc = GetLastError();
+ else if (ss.dwCurrentState != SERVICE_STOPPED)
+ rc = 0;
+ CloseServiceHandle(service);
+ }
+ CloseServiceHandle(scm);
+ return(rc);
+}
+
static void *start_status_routine( void *ptr )
{
if ( b->a_dn_at != NULL && op->o_ndn != NULL ) {
Attribute *at;
struct berval bv;
- int match;
+ int match = 0;
const char *text;
const char *desc = b->a_dn_at->ad_cname->bv_val;
/* see if asker is listed in dnattr */
for( at = attrs_find( e->e_attrs, b->a_dn_at );
- at == NULL;
- at = attrs_find( e->e_attrs->a_next, b->a_dn_at ) )
+ at != NULL;
+ at = attrs_find( at->a_next, b->a_dn_at ) )
{
if( value_find( b->a_dn_at, at->a_vals, &bv ) == 0 ) {
/* found it */
}
rc = 0;
+ grp_oc = oc_find( grpoc );
grpdn = (char *)ch_malloc(1024);
if (grp_oc != NULL && grp_ad != NULL && grpdn != NULL) {
} else if (aci_strbvcmp( "role", &bv ) == 0) {
if (aci_group_member(&sdn, SLAPD_ROLE_CLASS, SLAPD_ROLE_ATTR, be, e, op, matches))
return(1);
+
}
return(0);
goto done;
}
- desc.ad_lang = tokens[i];
+ desc.ad_lang = ch_strdup( tokens[i] );
/* normalize to all lower case, it's easy */
ldap_pvt_str2lower( desc.ad_lang );
#include "portable.h"
#include <stdio.h>
-
#include <ac/string.h>
#include <ac/time.h>
#include <ac/socket.h>
e->e_attrs = NULL;
e->e_private = NULL;
- Debug( LDAP_DEBUG_ARGS, " do_add: ndn (%s)\n", e->e_ndn, 0, 0 );
+ Debug( LDAP_DEBUG_ARGS, "do_add: ndn (%s)\n", e->e_ndn, 0, 0 );
/* get the attrs */
for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
goto done;
}
- if ( modlist == NULL )
- {
+ if ( modlist == NULL ) {
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "no attributes provided", NULL, NULL );
goto done;
/* make sure this backend recongizes critical controls */
rc = backend_check_controls( be, conn, op, &text ) ;
-
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto done;
}
+ /* check for referrals */
+ rc = backend_check_referrals( be, conn, op, e->e_dn, e->e_ndn );
+ if ( rc != LDAP_SUCCESS ) {
+ goto done;
+ }
+
if ( global_readonly || be->be_readonly ) {
Debug( LDAP_DEBUG_ANY, "do_add: database is read-only\n",
0, 0, 0 );
int
attr_merge(
- Entry *e,
+ Entry *e,
AttributeDescription *desc,
- struct berval **vals )
+ struct berval **vals )
{
Attribute **a;
# DNSSRV backend written by Kurt Zeilenga
##########################################################################
-SRCS = init.c bind.c search.c config.c compare.c \
- modify.c add.c modrdn.c delete.c request.c
-OBJS = init.lo bind.lo search.lo config.lo compare.lo \
- modify.lo add.lo modrdn.lo delete.lo request.lo
+SRCS = init.c bind.c search.c config.c referral.c
+OBJS = init.lo bind.lo search.lo config.lo referral.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
+++ /dev/null
-/* add.c - DNS SRV backend add function */
-/* $OpenLDAP$ */
-/*
- * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-dnssrv.h"
-
-int
-dnssrv_back_add(
- Backend *be,
- Connection *conn,
- Operation *op,
- Entry *e
-)
-{
- return dnssrv_back_request( be, conn, op, e->e_dn, e->e_ndn,
- 0, NULL, NULL, 0 );
-}
+++ /dev/null
-/* $OpenLDAP$ */
-/*
- * Copyright 2000, OpenLDAP Foundation, All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License. A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
- */
-
-#ifndef DNSSRV_BACK_H
-#define DNSSRV_BACK_H 1
-
-#include "external.h"
-
-LDAP_BEGIN_DECL
-
-int dnssrv_result();
-
-extern int dnssrv_back_request LDAP_P((
- BackendDB *bd,
- Connection *conn, Operation *op,
- const char *dn, const char *ndn,
- int scope, Filter *filter,
- char **attrs, int attrsonly ));
-
-LDAP_END_DECL
-
-#endif /* DNSSRV_BACK_H */
#include <ac/string.h>
#include "slap.h"
-#include "back-dnssrv.h"
+#include "external.h"
int
dnssrv_back_bind(
const char *ndn,
int method,
struct berval *cred,
- char **edn
-)
+ char **edn )
{
Debug( LDAP_DEBUG_TRACE, "DNSSRV: bind %s (%d)\n",
dn == NULL ? "" : dn,
AttributeAssertion *ava
)
{
- return dnssrv_back_request( be, conn, op, dn, ndn,
- 0, NULL, NULL, 0 );
+ assert( get_manageDSAit( op ) );
+
+ /* not implemented */
+
+ return LDAP_OTHER;
}
#include <ac/socket.h>
#include "slap.h"
-#include "back-dnssrv.h"
+#include "external.h"
int
dnssrv_back_db_config(
const char *fname,
int lineno,
int argc,
- char **argv
-)
+ char **argv )
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
char *port;
/* no configuration options (yet) */
{
fprintf( stderr,
-"%s: line %d: unknown directive \"%s\" in DNSSRV database definition (ignored)\n",
+ "%s: line %d: unknown directive \"%s\""
+ " in DNSSRV database definition (ignored)\n",
fname, lineno, argv[0] );
}
return 0;
+++ /dev/null
-/* delete.c - DNS SRV backend delete function */
-/* $OpenLDAP$ */
-/*
- * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-dnssrv.h"
-
-int
-dnssrv_back_delete(
- Backend *be,
- Connection *conn,
- Operation *op,
- const char *dn,
- const char *ndn
-)
-{
- return dnssrv_back_request( be, conn, op, dn, ndn,
- 0, NULL, NULL, 0 );
-}
Connection *conn, Operation *op,
const char *dn, const char *ndn, AttributeAssertion *ava ));
-extern int dnssrv_back_modify LDAP_P(( BackendDB *bd,
+extern int dnssrv_back_referrals LDAP_P(( BackendDB *bd,
Connection *conn, Operation *op,
const char *dn, const char *ndn,
- Modifications *ml ));
-
-extern int dnssrv_back_modrdn LDAP_P(( BackendDB *bd,
- Connection *conn, Operation *op,
- const char *dn, const char *ndn,
- const char *newrdn, int deleteoldrdn,
- const char *newSuperior ));
-
-extern int dnssrv_back_add LDAP_P(( BackendDB *bd,
- Connection *conn, Operation *op, Entry *e ));
-
-extern int dnssrv_back_delete LDAP_P(( BackendDB *bd,
- Connection *conn, Operation *op,
- const char *dn, const char *ndn ));
+ const char **text ));
LDAP_END_DECL
#include <ac/socket.h>
#include "slap.h"
-#include "back-dnssrv.h"
+#include "external.h"
#ifdef SLAPD_DNSSRV_DYNAMIC
-int back_dnssrv_LTX_init_module(int argc, char *argv[]) {
+int back_dnssrv_LTX_init_module(int argc, char *argv[])
+{
BackendInfo bi;
memset( &bi, '\0', sizeof(bi) );
bi.bi_type = "dnssrv";
bi.bi_init = dnssrv_back_initialize;
- backend_add(&bi);
+ backend_add( &bi );
return 0;
}
int
dnssrv_back_initialize(
- BackendInfo *bi
-)
+ BackendInfo *bi )
{
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
bi->bi_close = 0;
bi->bi_destroy = 0;
- bi->bi_db_init = dnssrv_back_db_init;
+ bi->bi_db_init = 0;
+ bi->bi_db_destroy = 0;
bi->bi_db_config = dnssrv_back_db_config;
bi->bi_db_open = 0;
bi->bi_db_close = 0;
- bi->bi_db_destroy = dnssrv_back_db_destroy;
+
+ bi->bi_chk_referrals = dnssrv_back_referrals;
bi->bi_op_bind = dnssrv_back_bind;
- bi->bi_op_unbind = 0;
bi->bi_op_search = dnssrv_back_search;
- bi->bi_op_compare = dnssrv_back_compare;
- bi->bi_op_modify = dnssrv_back_modify;
- bi->bi_op_modrdn = dnssrv_back_modrdn;
- bi->bi_op_add = dnssrv_back_add;
- bi->bi_op_delete = dnssrv_back_delete;
+ bi->bi_op_compare = 0 /* dnssrv_back_compare */;
+ bi->bi_op_modify = 0;
+ bi->bi_op_modrdn = 0;
+ bi->bi_op_add = 0;
+ bi->bi_op_delete = 0;
bi->bi_op_abandon = 0;
+ bi->bi_op_unbind = 0;
bi->bi_extended = 0;
-
bi->bi_acl_group = 0;
#ifdef HAVE_CYRUS_SASL
int
dnssrv_back_db_init(
- Backend *be
-)
+ Backend *be )
{
-#if 0
- struct ldapinfo *li;
-
- li = (struct ldapinfo *) ch_calloc( 1, sizeof(struct ldapinfo) );
- ldap_pvt_thread_mutex_init( &li->conn_mutex );
-
- be->be_private = li;
-
- return li == NULL;
-#else
return 0;
-#endif
}
int
dnssrv_back_db_destroy(
- Backend *be
-)
+ Backend *be )
{
-#if 0
- struct ldapinfo *li;
-
- if (be->be_private) {
- li = (struct ldapinfo *)be->be_private;
- if (li->host) {
- free(li->host);
- li->host = NULL;
- }
- ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
- }
-
- free( be->be_private );
- return 0;
-#else
return 0;
-#endif
}
+++ /dev/null
-/* modify.c - DNS SRV backend modify function */
-/* $OpenLDAP$ */
-/*
- * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-dnssrv.h"
-
-int
-dnssrv_back_modify(
- Backend *be,
- Connection *conn,
- Operation *op,
- const char *dn,
- const char *ndn,
- Modifications *ml
-)
-{
- return dnssrv_back_request( be, conn, op, dn, ndn,
- 0, NULL, NULL, 0 );
-}
+++ /dev/null
-/* modrdn.c - DNS SRV backend modrdn function */
-/* $OpenLDAP$ */
-/*
- * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/socket.h>
-#include <ac/string.h>
-
-#include "slap.h"
-#include "back-dnssrv.h"
-
-int
-dnssrv_back_modrdn(
- Backend *be,
- Connection *conn,
- Operation *op,
- const char *dn,
- const char *ndn,
- const char *newrdn,
- int deleteoldrdn,
- const char *newSuperior
-)
-{
- return dnssrv_back_request( be, conn, op, dn, ndn,
- 0, NULL, NULL, 0 );
-}
--- /dev/null
+/* referral.c - DNS SRV backend referral handler */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "external.h"
+
+int
+dnssrv_back_referrals(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ const char *dn,
+ const char *ndn,
+ const char **text )
+{
+ int i;
+ int rc = LDAP_OTHER;
+ char *domain = NULL;
+ char *hostlist = NULL;
+ char **hosts = NULL;
+ struct berval **urls = NULL;
+
+ if( ndn == NULL || *ndn == '\0' ) {
+ *text = "operation upon null (empty) DN disallowed";
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+
+ if( get_manageDSAit( op ) ) {
+ if( op->o_tag == LDAP_REQ_SEARCH ) {
+ return LDAP_SUCCESS;
+ }
+
+ *text = "DNS SRV problem processing manageDSAit control";
+ return LDAP_OTHER;
+ }
+
+ if( ldap_dn2domain( dn, &domain ) ) {
+ send_ldap_result( conn, op, LDAP_REFERRAL,
+ NULL, NULL, default_referral, NULL );
+ return LDAP_REFERRAL;
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
+ dn == NULL ? "" : dn,
+ domain == NULL ? "" : domain,
+ 0 );
+
+ if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
+ rc, 0, 0 );
+ *text = "no DNS SRV RR available for DN";
+ rc = LDAP_NO_SUCH_OBJECT;
+ goto done;
+ }
+
+ hosts = str2charray( hostlist, " " );
+
+ if( hosts == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
+ *text = "problem processing DNS SRV records for DN";
+ goto done;
+ }
+
+ for( i=0; hosts[i] != NULL; i++) {
+ struct berval *url = ch_malloc( sizeof( struct berval ) );
+
+ url->bv_len = sizeof("ldap://")-1 + strlen(hosts[i]);
+ url->bv_val = ch_malloc( url->bv_len + 1 );
+
+ strcpy( url->bv_val, "ldap://" );
+ strcpy( &url->bv_val[sizeof("ldap://")-1], hosts[i] );
+
+ if( ber_bvecadd( &urls, url ) < 0 ) {
+ ber_bvfree( url );
+ *text = "problem processing DNS SRV records for DN";
+ goto done;
+ }
+ }
+
+ Statslog( LDAP_DEBUG_STATS,
+ "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
+ op->o_connid, op->o_opid, op->o_protocol, dn, urls[0]->bv_val );
+
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> url=\"%s\"\n",
+ dn == NULL ? "" : dn,
+ urls[0]->bv_val, 0 );
+
+ send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+ NULL, "DNS SRV generated referrals", urls, NULL );
+
+done:
+ if( domain != NULL ) ch_free( domain );
+ if( hostlist != NULL ) ch_free( hostlist );
+ if( hosts != NULL ) charray_free( hosts );
+ ber_bvecfree( urls );
+ return rc;
+}
+++ /dev/null
-/* add.c - DNS SRV backend request handler */
-/* $OpenLDAP$ */
-/*
- * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include <ac/string.h>
-#include <ac/socket.h>
-
-#include "slap.h"
-#include "back-dnssrv.h"
-
-int
-dnssrv_back_request(
- Backend *be,
- Connection *conn,
- Operation *op,
- const char *dn,
- const char *ndn,
- int scope, Filter *filter,
- char **attrs, int attrsonly )
-{
- int i;
- int rc;
- char *domain = NULL;
- char *hostlist = NULL;
- char **hosts = NULL;
- struct berval **urls = NULL;
- int manageDSAit = get_manageDSAit( op );
-
- if( ndn == NULL || *ndn == '\0' ) {
- send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
- NULL, "operation upon null (empty) DN disallowed",
- NULL, NULL );
- goto done;
- }
-
- if( ldap_dn2domain( dn, &domain ) ) {
- send_ldap_result( conn, op, LDAP_REFERRAL,
- NULL, NULL, default_referral, NULL );
- goto done;
- }
-
- Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
- dn == NULL ? "" : dn,
- domain == NULL ? "" : domain,
- 0 );
-
- if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
- Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
- rc, 0, 0 );
- send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
- NULL, "no DNS SRV RR available for DN", NULL, NULL );
- goto done;
- }
-
- hosts = str2charray( hostlist, " " );
-
- if( hosts == NULL ) {
- Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
- send_ldap_result( conn, op, LDAP_OTHER,
- NULL, "problem processing DNS SRV records for DN", NULL, NULL );
- goto done;
- }
-
- for( i=0; hosts[i] != NULL; i++) {
- struct berval *url = ch_malloc( sizeof( struct berval ) );
-
- url->bv_len = sizeof("ldap://")-1 + strlen(hosts[i]);
- url->bv_val = ch_malloc( url->bv_len + 1 );
-
- strcpy( url->bv_val, "ldap://" );
- strcpy( &url->bv_val[sizeof("ldap://")-1], hosts[i] );
-
- if( ber_bvecadd( &urls, url ) < 0 ) {
- ber_bvfree( url );
- send_ldap_result( conn, op, LDAP_OTHER,
- NULL, "problem processing DNS SRV records for DN",
- NULL, NULL );
- goto done;
- }
- }
-
- Statslog( LDAP_DEBUG_STATS,
- "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
- op->o_connid, op->o_opid, op->o_protocol, dn, urls[0]->bv_val );
-
- Debug( LDAP_DEBUG_TRACE, "DNSSRV: %sdn=\"%s\" -> url=\"%s\"\n",
- manageDSAit ? "ManageDSAit " : "",
- dn == NULL ? "" : dn,
- urls[0]->bv_val );
-
- if( manageDSAit ) {
- char *refdn, *nrefdn;
- rc = ldap_domain2dn(domain, &refdn);
-
- if( rc != LDAP_SUCCESS ) {
- send_ldap_result( conn, op, LDAP_OTHER,
- NULL, "DNS SRV problem processing manageDSAit control",
- NULL, NULL );
- goto done;
- }
-
- nrefdn = ch_strdup( refdn );
- dn_normalize(nrefdn);
-
- if( strcmp( nrefdn, ndn ) != 0 ) {
- /* requested dn is subordinate */
-
- Debug( LDAP_DEBUG_TRACE,
- "DNSSRV: dn=\"%s\" subordindate to refdn=\"%s\"\n",
- dn == NULL ? "" : dn,
- refdn == NULL ? "" : refdn,
- NULL );
-
- send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
- refdn, NULL,
- NULL, NULL );
-
- } else if( op->o_tag != LDAP_REQ_SEARCH ) {
- send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
- dn, "DNS SRV ManageDSAIT control disallowed",
- NULL, NULL );
-
- } else if ( scope != LDAP_SCOPE_ONELEVEL ) {
- struct berval val;
- struct berval *vals[2];
- Entry *e = ch_calloc( 1, sizeof(Entry) );
- AttributeDescription *ad_objectClass
- = slap_schema.si_ad_objectClass;
- AttributeDescription *ad_ref = slap_schema.si_ad_ref;
- e->e_dn = strdup( dn );
- e->e_ndn = strdup( ndn );
-
- e->e_attrs = NULL;
- e->e_private = NULL;
-
- vals[0] = &val;
- vals[1] = NULL;
-
- val.bv_val = "top";
- val.bv_len = sizeof("top")-1;
- attr_merge( e, ad_objectClass, vals );
-
- val.bv_val = "referral";
- val.bv_len = sizeof("referral")-1;
- attr_merge( e, ad_objectClass, vals );
-
- val.bv_val = "extensibleObject";
- val.bv_len = sizeof("extensibleObject")-1;
- attr_merge( e, ad_objectClass, vals );
-
- {
- AttributeDescription *ad = NULL;
- const char *text;
-
- rc = slap_str2ad( "dc", &ad, &text );
-
- if( rc == LDAP_SUCCESS ) {
- char *p;
- val.bv_val = ch_strdup( domain );
-
- p = strchr( val.bv_val, '.' );
-
- if( p == val.bv_val ) {
- val.bv_val[1] = '\0';
- } else if ( p != NULL ) {
- *p = '\0';
- }
-
- val.bv_len = strlen(val.bv_val);
- attr_merge( e, ad, vals );
-
- ad_free( ad, 1 );
- }
- }
-
- {
- AttributeDescription *ad = NULL;
- const char *text;
-
- rc = slap_str2ad( "associatedDomain", &ad, &text );
-
- if( rc == LDAP_SUCCESS ) {
- val.bv_val = domain;
- val.bv_len = strlen(domain);
- attr_merge( e, ad, vals );
-
- ad_free( ad, 1 );
- }
- }
-
- attr_merge( e, ad_ref, urls );
-
- rc = test_filter( be, conn, op, e, filter );
-
- if( rc == LDAP_COMPARE_TRUE ) {
- send_search_entry( be, conn, op,
- e, attrs, attrsonly, NULL );
- }
-
- entry_free( e );
-
- send_ldap_result( conn, op, LDAP_SUCCESS,
- NULL, NULL, NULL, NULL );
-
- } else {
- send_ldap_result( conn, op, LDAP_SUCCESS,
- NULL, NULL, NULL, NULL );
- }
-
- free( refdn );
- free( nrefdn );
-
- } else {
- send_ldap_result( conn, op, LDAP_REFERRAL,
- NULL, "DNS SRV generated referrals", urls, NULL );
- }
-
-done:
- if( domain != NULL ) ch_free( domain );
- if( hostlist != NULL ) ch_free( hostlist );
- if( hosts != NULL ) charray_free( hosts );
- if( urls != NULL ) ber_bvecfree( urls );
- return 0;
-}
#include <ac/time.h>
#include "slap.h"
-#include "back-dnssrv.h"
+#include "external.h"
int
dnssrv_back_search(
Filter *filter,
const char *filterstr,
char **attrs,
- int attrsonly
-)
+ int attrsonly )
{
- return dnssrv_back_request( be, conn, op, dn, ndn,
- scope, filter, attrs, attrsonly );
+ int i;
+ int rc;
+ char *domain = NULL;
+ char *hostlist = NULL;
+ char **hosts = NULL;
+ char *refdn, *nrefdn;
+ struct berval **urls = NULL;
+
+ assert( get_manageDSAit( op ) );
+
+ if( ldap_dn2domain( dn, &domain ) ) {
+ send_ldap_result( conn, op, LDAP_REFERRAL,
+ NULL, NULL, default_referral, NULL );
+ goto done;
+ }
+
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
+ dn == NULL ? "" : dn,
+ domain == NULL ? "" : domain,
+ 0 );
+
+ if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
+ rc, 0, 0 );
+ send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
+ NULL, "no DNS SRV RR available for DN", NULL, NULL );
+ goto done;
+ }
+
+ hosts = str2charray( hostlist, " " );
+
+ if( hosts == NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
+ send_ldap_result( conn, op, LDAP_OTHER,
+ NULL, "problem processing DNS SRV records for DN", NULL, NULL );
+ goto done;
+ }
+
+ for( i=0; hosts[i] != NULL; i++) {
+ struct berval *url = ch_malloc( sizeof( struct berval ) );
+
+ url->bv_len = sizeof("ldap://")-1 + strlen(hosts[i]);
+ url->bv_val = ch_malloc( url->bv_len + 1 );
+
+ strcpy( url->bv_val, "ldap://" );
+ strcpy( &url->bv_val[sizeof("ldap://")-1], hosts[i] );
+
+ if( ber_bvecadd( &urls, url ) < 0 ) {
+ ber_bvfree( url );
+ send_ldap_result( conn, op, LDAP_OTHER,
+ NULL, "problem processing DNS SRV records for DN",
+ NULL, NULL );
+ goto done;
+ }
+ }
+
+ Statslog( LDAP_DEBUG_STATS,
+ "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
+ op->o_connid, op->o_opid, op->o_protocol, dn, urls[0]->bv_val );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n",
+ scope,
+ dn == NULL ? "" : dn,
+ urls[0]->bv_val );
+
+ rc = ldap_domain2dn(domain, &refdn);
+
+ if( rc != LDAP_SUCCESS ) {
+ send_ldap_result( conn, op, LDAP_OTHER,
+ NULL, "DNS SRV problem processing manageDSAit control",
+ NULL, NULL );
+ goto done;
+ }
+
+ nrefdn = ch_strdup( refdn );
+ dn_normalize(nrefdn);
+
+ if( strcmp( nrefdn, ndn ) != 0 ) {
+ /* requested dn is subordinate */
+
+ Debug( LDAP_DEBUG_TRACE,
+ "DNSSRV: dn=\"%s\" subordindate to refdn=\"%s\"\n",
+ dn == NULL ? "" : dn,
+ refdn == NULL ? "" : refdn,
+ NULL );
+
+ send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
+ refdn, NULL,
+ NULL, NULL );
+
+ } else if ( scope == LDAP_SCOPE_ONELEVEL ) {
+ send_ldap_result( conn, op, LDAP_SUCCESS,
+ NULL, NULL, NULL, NULL );
+
+ } else {
+ struct berval val;
+ struct berval *vals[2];
+ Entry *e = ch_calloc( 1, sizeof(Entry) );
+ AttributeDescription *ad_objectClass
+ = slap_schema.si_ad_objectClass;
+ AttributeDescription *ad_ref = slap_schema.si_ad_ref;
+ e->e_dn = strdup( dn );
+ e->e_ndn = strdup( ndn );
+
+ e->e_attrs = NULL;
+ e->e_private = NULL;
+
+ vals[0] = &val;
+ vals[1] = NULL;
+
+ val.bv_val = "top";
+ val.bv_len = sizeof("top")-1;
+ attr_merge( e, ad_objectClass, vals );
+
+ val.bv_val = "referral";
+ val.bv_len = sizeof("referral")-1;
+ attr_merge( e, ad_objectClass, vals );
+
+ val.bv_val = "extensibleObject";
+ val.bv_len = sizeof("extensibleObject")-1;
+ attr_merge( e, ad_objectClass, vals );
+
+ {
+ AttributeDescription *ad = NULL;
+ const char *text;
+
+ rc = slap_str2ad( "dc", &ad, &text );
+
+ if( rc == LDAP_SUCCESS ) {
+ char *p;
+ val.bv_val = ch_strdup( domain );
+
+ p = strchr( val.bv_val, '.' );
+
+ if( p == val.bv_val ) {
+ val.bv_val[1] = '\0';
+ } else if ( p != NULL ) {
+ *p = '\0';
+ }
+
+ val.bv_len = strlen(val.bv_val);
+ attr_merge( e, ad, vals );
+
+ ad_free( ad, 1 );
+ }
+ }
+
+ {
+ AttributeDescription *ad = NULL;
+ const char *text;
+
+ rc = slap_str2ad( "associatedDomain", &ad, &text );
+
+ if( rc == LDAP_SUCCESS ) {
+ val.bv_val = domain;
+ val.bv_len = strlen(domain);
+ attr_merge( e, ad, vals );
+
+ ad_free( ad, 1 );
+ }
+ }
+
+ attr_merge( e, ad_ref, urls );
+
+ rc = test_filter( be, conn, op, e, filter );
+
+ if( rc == LDAP_COMPARE_TRUE ) {
+ send_search_entry( be, conn, op,
+ e, attrs, attrsonly, NULL );
+ }
+
+ entry_free( e );
+
+ send_ldap_result( conn, op, LDAP_SUCCESS,
+ NULL, NULL, NULL, NULL );
+ }
+
+ free( refdn );
+ free( nrefdn );
+
+done:
+ if( domain != NULL ) ch_free( domain );
+ if( hostlist != NULL ) ch_free( hostlist );
+ if( hosts != NULL ) charray_free( hosts );
+ if( urls != NULL ) ber_bvecfree( urls );
+ return 0;
}
bi->bi_extended = 0;
bi->bi_acl_group = ldap_back_group;
+ bi->bi_chk_referrals = 0;
#ifdef HAVE_CYRUS_SASL
bi->bi_sasl_authorize = 0;
index.c id2children.c nextid.c abandon.c compare.c group.c \
modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
filterindex.c unbind.c close.c alias.c tools.c key.c \
- extended.c passwd.c sasl.c
+ extended.c passwd.c sasl.c referral.c
OBJS = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo id2entry.lo \
index.lo id2children.lo nextid.lo abandon.lo compare.lo group.lo \
modify.lo modrdn.lo delete.lo init.lo config.lo bind.lo attr.lo \
filterindex.lo unbind.lo close.lo alias.lo tools.lo key.lo \
- extended.lo passwd.lo sasl.lo
+ extended.lo passwd.lo sasl.lo referral.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
unsigned depth;
char **dnlist;
- assert( ( alias != NULL && dn == NULL ) || ( alias == NULL && dn != NULL ) );
+ assert( ( alias != NULL && dn_in == NULL )
+ || ( alias == NULL && dn_in != NULL ) );
*matched = NULL;
*err = LDAP_SUCCESS;
/* check if aliasDN is a subordinate of any DN in our list */
if( dnlist_subordinate( dnlist, aliasDN ) ) {
+ ch_free( aliasDN );
*matched = entry;
entry = NULL;
*err = LDAP_ALIAS_PROBLEM;
/* attempt to dereference alias */
newe = dn2entry_r( be, aliasDN, &sup );
+ ch_free( aliasDN );
if( newe != NULL ) {
free( dn );
dn = ch_strdup( entry->e_ndn );
charray_add( &dnlist, dn );
continue;
-
}
if ( sup != NULL ) {
}
aliasDN = new_superior( dn, sup->e_ndn, supDN );
+ free(supDN);
if( aliasDN == NULL ) {
free(aliasDN);
int *err,
const char **errmsg )
{
+ char *dn;
Attribute *a;
AttributeDescription *aliasedObjectName = slap_schema.si_ad_aliasedObjectName;
return NULL;
}
- return a->a_vals[0]->bv_val;
+ dn = ch_strdup( a->a_vals[0]->bv_val );
+
+ if( dn_normalize(dn) == NULL ) {
+ ch_free( dn );
+ *err = LDAP_ALIAS_PROBLEM;
+ *errmsg = "alias aliasedObjectName value is invalid";
+ return NULL;
+ }
+
+ return dn;
}
char* new_superior(
int dbc_maxids;
int dbc_maxindirect;
int dbc_dirty;
+ int dbc_flags;
time_t dbc_lastref;
long dbc_blksize;
char *dbc_name;
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- int i, lru;
+ int i, lru, empty;
time_t oldtime, curtime;
char buf[MAXPATHLEN];
#ifdef HAVE_ST_BLKSIZE
Debug( LDAP_DEBUG_TRACE, "=> ldbm_cache_open( \"%s\", %d, %o )\n", buf,
flags, li->li_mode );
- lru = 0;
curtime = slap_get_time();
- oldtime = curtime;
+ empty = MAXDBCACHE;
ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
- for ( i = 0; i < MAXDBCACHE && li->li_dbcache[i].dbc_name != NULL;
- i++ ) {
- /* already open - return it */
- if ( strcmp( li->li_dbcache[i].dbc_name, buf ) == 0 ) {
- li->li_dbcache[i].dbc_refcnt++;
- Debug( LDAP_DEBUG_TRACE,
- "<= ldbm_cache_open (cache %d)\n", i, 0, 0 );
- ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
- return( &li->li_dbcache[i] );
- }
+ do {
+ lru = 0;
+ oldtime = curtime;
+ for ( i = 0; i < MAXDBCACHE; i++ ) {
+ /* see if this slot is free */
+ if ( li->li_dbcache[i].dbc_name == NULL) {
+ if (empty == MAXDBCACHE)
+ empty = i;
+ continue;
+ }
+
+ if ( strcmp( li->li_dbcache[i].dbc_name, buf ) == 0 ) {
+ /* already open - return it */
+ if (li->li_dbcache[i].dbc_flags != flags
+ && li->li_dbcache[i].dbc_refcnt == 0)
+ {
+ /* we don't want to use an open cache with different
+ * permissions (esp. if we need write but the open
+ * cache is read-only). So close this one if
+ * possible, and re-open below.
+ *
+ * FIXME: what about the case where the refcount
+ * is > 0? right now, we're using it anyway and
+ * just praying. Can there be more than one open
+ * cache to the same db?
+ *
+ * Also, it's really only necessary to compare the
+ * read-only flag, instead of all of the flags,
+ * but for now I'm checking all of them.
+ */
+ lru = i;
+ empty = MAXDBCACHE;
+ break;
+ }
+ li->li_dbcache[i].dbc_refcnt++;
+ Debug( LDAP_DEBUG_TRACE,
+ "<= ldbm_cache_open (cache %d)\n", i, 0, 0 );
+ ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
+ return( &li->li_dbcache[i] );
+ }
- /* keep track of lru db */
- if ( li->li_dbcache[i].dbc_lastref < oldtime &&
- li->li_dbcache[i].dbc_refcnt == 0 ) {
- lru = i;
- oldtime = li->li_dbcache[i].dbc_lastref;
+ /* keep track of lru db */
+ if ( li->li_dbcache[i].dbc_lastref < oldtime
+ && li->li_dbcache[i].dbc_refcnt == 0 )
+ {
+ lru = i;
+ oldtime = li->li_dbcache[i].dbc_lastref;
+ }
}
- }
- /* no empty slots, not already open - close lru and use that slot */
- if ( i == MAXDBCACHE ) {
- i = lru;
- if ( li->li_dbcache[i].dbc_refcnt != 0 ) {
- Debug( LDAP_DEBUG_ANY,
- "ldbm_cache_open no unused db to close - waiting\n",
- 0, 0, 0 );
- lru = -1;
- while ( lru == -1 ) {
+ i = empty;
+ if ( i == MAXDBCACHE ) {
+ /* no empty slots, not already open - close lru and use that slot */
+ if ( li->li_dbcache[lru].dbc_refcnt == 0 ) {
+ i = lru;
+ ldbm_close( li->li_dbcache[i].dbc_db );
+ free( li->li_dbcache[i].dbc_name );
+ li->li_dbcache[i].dbc_name = NULL;
+ } else {
+ Debug( LDAP_DEBUG_ANY,
+ "ldbm_cache_open no unused db to close - waiting\n",
+ 0, 0, 0 );
ldap_pvt_thread_cond_wait( &li->li_dbcache_cv,
- &li->li_dbcache_mutex );
- for ( i = 0; i < MAXDBCACHE; i++ ) {
- if ( li->li_dbcache[i].dbc_refcnt
- == 0 ) {
- lru = i;
- break;
- }
- }
+ &li->li_dbcache_mutex );
+ /* after waiting for a free slot, go back to square
+ * one: look for an open cache for this db, or an
+ * empty slot, or an unref'ed cache, or wait again.
+ */
}
- i = lru;
}
- ldbm_close( li->li_dbcache[i].dbc_db );
- free( li->li_dbcache[i].dbc_name );
- li->li_dbcache[i].dbc_name = NULL;
- }
+ } while (i == MAXDBCACHE);
if ( (li->li_dbcache[i].dbc_db = ldbm_open( buf, flags, li->li_mode,
- li->li_dbcachesize )) == NULL ) {
+ li->li_dbcachesize )) == NULL )
+ {
int err = errno;
Debug( LDAP_DEBUG_TRACE,
"<= ldbm_cache_open NULL \"%s\" errno=%d reason=\"%s\")\n",
li->li_dbcache[i].dbc_name = ch_strdup( buf );
li->li_dbcache[i].dbc_refcnt = 1;
li->li_dbcache[i].dbc_lastref = curtime;
+ li->li_dbcache[i].dbc_flags = flags;
li->li_dbcache[i].dbc_dirty = 0;
#ifdef HAVE_ST_BLKSIZE
if ( stat( buf, &st ) == 0 ) {
}
ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
- if ( --db->dbc_refcnt == 0 ) {
+ if ( --db->dbc_refcnt <= 0 ) {
+ db->dbc_refcnt = 0;
ldap_pvt_thread_cond_signal( &li->li_dbcache_cv );
}
ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
- if ( --db->dbc_refcnt == 0 ) {
+ if ( --db->dbc_refcnt <= 0 ) {
+ db->dbc_refcnt = 0;
ldap_pvt_thread_cond_signal( &li->li_dbcache_cv );
ldbm_close( db->dbc_db );
free( db->dbc_name );
struct berval **bv, ID id, int op ));
extern int ldbm_tool_sync LDAP_P(( BackendDB *be ));
-
+extern int ldbm_back_referrals LDAP_P(( BackendDB *bd,
+ Connection *conn, Operation *op,
+ const char *dn, const char *ndn,
+ const char **text ));
+
LDAP_END_DECL
#endif /* _LDBM_EXTERNAL_H */
goto return_results;
}
- if( is_entry_objectclass( e, group_oc ) ) {
+ if( !is_entry_objectclass( e, group_oc ) ) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: failed to find %s in objectClass\n",
group_oc_name, 0, 0 );
bv.bv_val = (char *) op_ndn;
bv.bv_len = strlen( op_ndn );
- if( value_find( group_at, attr->a_vals, &bv ) == 0 ) {
+ if( value_find( group_at, attr->a_vals, &bv ) != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: \"%s\" not in \"%s\": %s\n",
op_ndn, gr_ndn, group_at_name );
static ID_BLOCK* idl_dup( ID_BLOCK *idl );
-static void cont_alloc( Datum cont, Datum key )
+static void cont_alloc( Datum *cont, Datum *key )
{
- ldbm_datum_init( cont );
- cont.dsize = 1 + sizeof(ID) + key.dsize;
- cont.dptr = ch_malloc( cont.dsize );
+ ldbm_datum_init( *cont );
+ cont->dsize = 1 + sizeof(ID) + key->dsize;
+ cont->dptr = ch_malloc( cont->dsize );
- memcpy( &((unsigned char *)cont.dptr)[1 + sizeof(ID)],
- key.dptr, key.dsize );
+ * (unsigned char *) cont->dptr = SLAP_INDEX_CONT_PREFIX;
+
+ memcpy( &((unsigned char *)cont->dptr)[1 + sizeof(ID)],
+ key->dptr, key->dsize );
}
-static void cont_id( Datum cont, ID id )
+static void cont_id( Datum *cont, ID id )
{
int i;
for( i=1; i <= sizeof(id); i++) {
- ((unsigned char *)cont.dptr)[i] = (unsigned char)(id & 0xFF);
+ ((unsigned char *)cont->dptr)[i] = (unsigned char)(id & 0xFF);
id >>= 8;
}
}
-static void cont_free( Datum cont )
+static void cont_free( Datum *cont )
{
- ch_free( cont.dptr );
+ ch_free( cont->dptr );
}
/* Allocate an ID_BLOCK with room for nids ids */
tmp = (ID_BLOCK **) ch_malloc( (i + 1) * sizeof(ID_BLOCK *) );
/* read in all the blocks */
- cont_alloc( data, key );
+ cont_alloc( &data, &key );
nids = 0;
for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ ) {
- cont_id( data, ID_BLOCK_ID(idl, i) );
+ cont_id( &data, ID_BLOCK_ID(idl, i) );
if ( (tmp[i] = idl_fetch_one( be, db, data )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
nids += ID_BLOCK_NIDS(tmp[i]);
}
tmp[i] = NULL;
- cont_free( data );
+ cont_free( &data );
idl_free( idl );
/* allocate space for the big block */
}
/* write block with new key */
- cont_id( bkey, ID_BLOCK_ID(b, 0) );
+ cont_id( &bkey, ID_BLOCK_ID(b, 0) );
if ( (rc = idl_store( be, db, bkey, b )) != 0 ) {
Debug( LDAP_DEBUG_ANY,
/* store it */
rc = idl_store( be, db, key, idl );
- cont_alloc( k2, key );
- cont_id( k2, ID_BLOCK_ID(tmp, 0) );
+ cont_alloc( &k2, &key );
+ cont_id( &k2, ID_BLOCK_ID(tmp, 0) );
rc = idl_store( be, db, k2, tmp );
- cont_id( k2, ID_BLOCK_ID(tmp2, 0) );
+ cont_id( &k2, ID_BLOCK_ID(tmp2, 0) );
rc = idl_store( be, db, k2, tmp2 );
- cont_free( k2 );
+ cont_free( &k2 );
idl_free( tmp );
idl_free( tmp2 );
}
/* get the block */
- cont_alloc( k2, key );
- cont_id( k2, ID_BLOCK_ID(idl, i) );
+ cont_alloc( &k2, &key );
+ cont_id( &k2, ID_BLOCK_ID(idl, i) );
if ( (tmp = idl_fetch_one( be, db, k2 )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "idl_insert_key: nonexistent continuation block\n",
0, 0, 0 );
- cont_free( k2 );
+ cont_free( &k2 );
idl_free( idl );
return( -1 );
}
/* is there a next block? */
if ( !first && !ID_BLOCK_NOID(idl, i + 1) ) {
/* read it in */
- cont_alloc( k2, key );
- cont_id( k2, ID_BLOCK_ID(idl, i) );
+ cont_alloc( &k2, &key );
+ cont_id( &k2, ID_BLOCK_ID(idl, i) );
if ( (tmp2 = idl_fetch_one( be, db, k2 )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"idl_insert_key: idl_fetch_one returned NULL\n",
0, 0, 0 );
/* split the original block */
- cont_free( k2 );
+ cont_free( &k2 );
goto split;
}
/* delete all indirect blocks */
for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ ) {
- cont_id( k2, ID_BLOCK_ID(idl, j) );
+ cont_id( &k2, ID_BLOCK_ID(idl, j) );
rc = ldbm_cache_delete( db, k2 );
}
idl = idl_allids( be );
rc = idl_store( be, db, key, idl );
- cont_free( k2 );
+ cont_free( &k2 );
idl_free( idl );
idl_free( tmp );
return( rc );
rc = idl_store( be, db, key, tmp );
/* store the first id block */
- cont_id( k2, ID_BLOCK_ID(tmp2, 0) );
+ cont_id( &k2, ID_BLOCK_ID(tmp2, 0) );
rc = idl_store( be, db, k2, tmp2 );
/* store the second id block */
- cont_id( k2, ID_BLOCK_ID(tmp3, 0) );
+ cont_id( &k2, ID_BLOCK_ID(tmp3, 0) );
rc = idl_store( be, db, k2, tmp3 );
idl_free( tmp2 );
break;
}
- cont_free( k2 );
+ cont_free( &k2 );
idl_free( tmp );
idl_free( idl );
return( rc );
for ( nids = 0; !ID_BLOCK_NOID(idl, nids); nids++ )
; /* NULL */
- cont_alloc( data, key );
+ cont_alloc( &data, &key );
for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ )
{
ID_BLOCK *tmp;
- cont_id( data, ID_BLOCK_ID(idl, j) );
+ cont_id( &data, ID_BLOCK_ID(idl, j) );
if ( (tmp = idl_fetch_one( be, db, data )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
idl_store( be, db, key, idl );
}
idl_free( tmp );
- cont_free( data );
+ cont_free( &data );
idl_free( idl );
return 0;
}
idl_free( tmp );
}
- cont_free( data );
+ cont_free( &data );
idl_free( idl );
return -1;
}
bi->bi_entry_release_rw = ldbm_back_entry_release_rw;
bi->bi_acl_group = ldbm_back_group;
+ bi->bi_chk_referrals = ldbm_back_referrals;
/*
* hooks for slap tools
/* char *desc = mod->sm_desc->ad_cname->bv_val; */
MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
- if( mr == NULL ) {
- return LDAP_INAPPROPRIATE_MATCHING;
- }
-
-
a = attr_find( e->e_attrs, mod->sm_desc );
/* check if the values we're adding already exist */
if ( a != NULL ) {
+ if( mr == NULL || !mr->smr_match ) {
+ /* do not allow add of additional attribute
+ if no equality rule exists */
+ return LDAP_INAPPROPRIATE_MATCHING;
+ }
+
for ( i = 0; mod->sm_bvalues[i] != NULL; i++ ) {
int rc;
int j;
char *desc = mod->sm_desc->ad_cname->bv_val;
MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
- if( mr == NULL || !mr->smr_match ) {
- return LDAP_INAPPROPRIATE_MATCHING;
- }
-
/* delete the entire attribute */
if ( mod->sm_bvalues == NULL ) {
Debug( LDAP_DEBUG_ARGS, "removing entire attribute %s\n",
LDAP_NO_SUCH_ATTRIBUTE : LDAP_SUCCESS );
}
+ if( mr == NULL || !mr->smr_match ) {
+ /* disallow specific attributes from being deleted if
+ no equality rule */
+ return LDAP_INAPPROPRIATE_MATCHING;
+ }
+
/* delete specific values - find the attribute first */
if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
Debug( LDAP_DEBUG_ARGS, "ldap_modify_delete: "
--- /dev/null
+/* referral.c - LDBM backend referral handler */
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "slap.h"
+#include "back-ldbm.h"
+
+int
+ldbm_back_referrals(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ const char *dn,
+ const char *ndn,
+ const char **text )
+{
+ struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+ int rc = LDAP_SUCCESS;
+ Entry *e, *matched;
+
+ if( op->o_tag == LDAP_REQ_SEARCH ) {
+ /* let search take care of itself */
+ return rc;
+ }
+
+ if( get_manageDSAit( op ) ) {
+ /* let op take care of DSA management */
+ return rc;
+ }
+
+ /* get entry with reader lock */
+ e = dn2entry_r( be, ndn, &matched );
+ if ( e == NULL ) {
+ char *matched_dn = NULL;
+ struct berval **refs = default_referral;
+
+ if ( matched != NULL ) {
+ matched_dn = ch_strdup( matched->e_dn );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
+ op->o_tag, dn, matched_dn );
+
+ refs = is_entry_referral( matched )
+ ? get_entry_referrals( be, conn, op, matched )
+ : NULL;
+
+ cache_return_entry_r( &li->li_cache, matched );
+ }
+
+ if( refs != NULL ) {
+ /* send referrals */
+ send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+ matched_dn, NULL, refs, NULL );
+ }
+
+ if( matched != NULL ) {
+ ber_bvecfree( refs );
+ free( matched_dn );
+ }
+
+ return rc;
+ }
+
+ if ( is_entry_referral( e ) ) {
+ /* entry is a referral */
+ struct berval **refs = get_entry_referrals( be,
+ conn, op, e );
+
+ Debug( LDAP_DEBUG_TRACE,
+ "ldbm_referrals: op=%ld target=\"%s\" matched=\"%s\"\n",
+ op->o_tag, dn, e->e_dn );
+
+ if( refs != NULL ) {
+ send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+ e->e_dn, NULL, refs, NULL );
+ }
+
+ ber_bvecfree( refs );
+ }
+
+ cache_return_entry_r( &li->li_cache, e );
+ return rc;
+}
Filter *filter,
const char *filterstr,
char **attrs,
- int attrsonly
-)
+ int attrsonly )
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
int rc, err;
return 1;
}
+ if ( is_entry_alias( e ) ) {
+ /* don't deref */
+ deref = LDAP_DEREF_NEVER;
+ }
+
if ( tlimit == 0 && be_isroot( be, op->o_ndn ) ) {
tlimit = -1; /* allow root to set no limit */
} else {
}
if (e) {
- int result;
-#ifdef BROKEN_NUM_SUBORDINATES
- /* Tack on subordinates attr */
- ID_BLOCK *idl = NULL;
- char CATTR_SUBS[] = "numsubordinates";
-
- if (attrs &&
- charray_inlist(attrs,
- CATTR_SUBS))
- {
- idl = dn2idl(be, e->e_ndn,
- DN_ONE_PREFIX);
- if (idl)
- {
- char buf[30];
- struct berval val, *vals[2];
-
- vals[0] = &val;
- vals[1] = NULL;
-
- sprintf(buf, "%lu",
- ID_BLOCK_NIDS(idl));
-
- val.bv_val = buf;
- val.bv_len = strlen(buf);
-
- attr_merge(e, CATTR_SUBS,
- vals);
- }
- }
-#endif
-
- result = send_search_entry(be, conn, op,
+ int result = send_search_entry(be, conn, op,
e, attrs, attrsonly, NULL);
-#ifdef BROKEN_NUM_SUBORDINATES
- if (idl)
- {
- idl_free(idl);
- attr_delete(&e->e_attrs,
- CATTR_SUBS);
- }
-#endif
-
- switch (result)
- {
+ switch (result) {
case 0: /* entry sent ok */
nentries++;
break;
static ID_BLOCK *
base_candidate(
Backend *be,
- Entry *e
-)
+ Entry *e )
{
ID_BLOCK *idl;
Filter *filter,
int scope,
int deref,
- int manageDSAit
-)
+ int manageDSAit )
{
ID_BLOCK *candidates;
- candidates = filter_candidates( be, filter );
+ Filter f, fand, rf, af, xf;
+ AttributeAssertion aa_ref, aa_alias;
+ static struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
+ static struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" };
+
+ Debug(LDAP_DEBUG_TRACE, "search_candidates: base=\"%s\" s=%d d=%d\n",
+ e->e_ndn, scope, deref );
+
+ xf.f_or = filter;
+ xf.f_choice = LDAP_FILTER_OR;
+ xf.f_next = NULL;
+
+ if( !manageDSAit ) {
+ /* match referrals */
+ rf.f_choice = LDAP_FILTER_EQUALITY;
+ rf.f_ava = &aa_ref;
+ rf.f_av_desc = slap_schema.si_ad_objectClass;
+ rf.f_av_value = &bv_ref;
+ rf.f_next = xf.f_or;
+ xf.f_or = &rf;
+ }
+
+ if( deref & LDAP_DEREF_SEARCHING ) {
+ /* match aliases */
+ af.f_choice = LDAP_FILTER_EQUALITY;
+ af.f_ava = &aa_alias;
+ af.f_av_desc = slap_schema.si_ad_objectClass;
+ af.f_av_value = &bv_alias;
+ af.f_next = xf.f_or;
+ xf.f_or = ⁡
+ }
+
+ f.f_next = NULL;
+ f.f_choice = LDAP_FILTER_AND;
+ f.f_and = &fand;
+ fand.f_choice = scope == LDAP_SCOPE_SUBTREE
+ ? SLAPD_FILTER_DN_SUBTREE
+ : SLAPD_FILTER_DN_ONE;
+ fand.f_dn = e->e_ndn;
+ fand.f_next = xf.f_or == filter ? filter : &xf ;
+
+ candidates = filter_candidates( be, &f );
return( candidates );
}
bi->bi_extended = 0;
bi->bi_acl_group = 0;
+ bi->bi_chk_referrals = 0;
#ifdef HAVE_CYRUS_SASL
bi->bi_sasl_authorize = 0;
bi->bi_extended = 0;
bi->bi_acl_group = 0;
+ bi->bi_chk_referrals = 0;
#ifdef HAVE_CYRUS_SASL
bi->bi_sasl_authorize = 0;
return LDAP_SUCCESS;
}
+int backend_check_referrals(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ const char *dn,
+ const char *ndn )
+{
+ int rc = LDAP_SUCCESS;
+
+ if( be->be_chk_referrals ) {
+ const char *text;
+
+ rc = be->be_chk_referrals( be,
+ conn, op, dn, ndn, &text );
+
+ if( rc != LDAP_SUCCESS && rc != LDAP_REFERRAL ) {
+ send_ldap_result( conn, op, rc,
+ NULL, text, NULL, NULL );
+ }
+ }
+
+ return rc;
+}
+
int
backend_group(
Backend *be,
#include "portable.h"
#include <stdio.h>
-
#include <ac/socket.h>
#include "ldap_pvt.h"
int rc = LDAP_SUCCESS;
const char *text = NULL;
+ ava.aa_desc = NULL;
desc.bv_val = NULL;
value.bv_val = NULL;
goto cleanup;
}
- ava.aa_desc = NULL;
+ /*
+ * We could be serving multiple database backends. Select the
+ * appropriate one, or send a referral to our "referral server"
+ * if we don't hold it.
+ */
+ if ( (be = select_backend( ndn )) == NULL ) {
+ send_ldap_result( conn, op, rc = LDAP_REFERRAL,
+ NULL, NULL, default_referral, NULL );
+ rc = 1;
+ goto cleanup;
+ }
+
+ /* make sure this backend recongizes critical controls */
+ rc = backend_check_controls( be, conn, op, &text ) ;
+ if( rc != LDAP_SUCCESS ) {
+ send_ldap_result( conn, op, rc,
+ NULL, text, NULL, NULL );
+ goto cleanup;
+ }
+
+ /* check for referrals */
+ rc = backend_check_referrals( be, conn, op, dn, ndn );
+ if ( rc != LDAP_SUCCESS ) {
+ goto cleanup;
+ }
+
rc = slap_bv2ad( &desc, &ava.aa_desc, &text );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc, NULL,
op->o_connid, op->o_opid, dn, ava.aa_desc->ad_cname->bv_val, 0 );
-
- /*
- * We could be serving multiple database backends. Select the
- * appropriate one, or send a referral to our "referral server"
- * if we don't hold it.
- */
- if ( (be = select_backend( ndn )) == NULL ) {
- send_ldap_result( conn, op, rc = LDAP_REFERRAL,
- NULL, NULL, default_referral, NULL );
- rc = 1;
- goto cleanup;
- }
-
- /* make sure this backend recongizes critical controls */
- rc = backend_check_controls( be, conn, op, &text ) ;
-
- if( rc != LDAP_SUCCESS ) {
- send_ldap_result( conn, op, rc,
- NULL, text, NULL, NULL );
- goto cleanup;
- }
-
/* deref suffix alias if appropriate */
ndn = suffix_alias( be, ndn );
}
errno = 0;
- if ( (tag = ber_get_next( conn->c_sb, &len, conn->c_currentber ))
- != LDAP_TAG_MESSAGE )
- {
+
+ tag = ber_get_next( conn->c_sb, &len, conn->c_currentber );
+ if ( tag != LDAP_TAG_MESSAGE ) {
int err = errno;
ber_socket_t sd;
/* make sure this backend recongizes critical controls */
rc = backend_check_controls( be, conn, op, &text ) ;
-
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto cleanup;
}
+ /* check for referrals */
+ rc = backend_check_referrals( be, conn, op, dn, ndn );
+ if ( rc != LDAP_SUCCESS ) {
+ goto cleanup;
+ }
+
if ( global_readonly || be->be_readonly ) {
Debug( LDAP_DEBUG_ANY, "do_delete: database is read-only\n",
0, 0, 0 );
*d++ = *s;
}
break;
+
case B4SEPARATOR:
if ( RDN_SEPARATOR( *s ) ) {
state = B4TYPE;
*d++ = *s;
}
break;
+
default:
dn = NULL;
Debug( LDAP_DEBUG_ANY,
"dn_validate - unknown state %d\n", state, 0, 0 );
break;
}
+
if ( *s == '\\' ) {
gotesc = 1;
} else {
}
while(*dn_in && ASCII_SPACE(*dn_in)) {
- dn++;
+ dn_in++;
}
if( *dn_in == '\0' ) {
#include "slap.h"
-
int
do_modify(
Connection *conn,
- Operation *op
-)
+ Operation *op )
{
char *dn, *ndn = NULL;
char *last;
}
(*modtail)->ml_op = mop;
-
-
modtail = &(*modtail)->ml_next;
}
*modtail = NULL;
}
#endif
-
Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MOD dn=\"%s\"\n",
op->o_connid, op->o_opid, dn, 0, 0 );
/* make sure this backend recongizes critical controls */
rc = backend_check_controls( be, conn, op, &text ) ;
-
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto cleanup;
}
+ /* check for referrals */
+ rc = backend_check_referrals( be, conn, op, dn, ndn );
+ if ( rc != LDAP_SUCCESS ) {
+ goto cleanup;
+ }
+
if ( global_readonly || be->be_readonly ) {
Debug( LDAP_DEBUG_ANY, "do_modify: database is read-only\n",
0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
- NULL, "directory is read-only", NULL, NULL );
+ NULL, "directory is read-only", NULL, NULL );
goto cleanup;
}
/* make sure this backend recongizes critical controls */
rc = backend_check_controls( be, conn, op, &text ) ;
-
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto cleanup;
}
+ /* check for referrals */
+ rc = backend_check_referrals( be, conn, op, dn, ndn );
+ if ( rc != LDAP_SUCCESS ) {
+ goto cleanup;
+ }
+
if ( global_readonly || be->be_readonly ) {
Debug( LDAP_DEBUG_ANY, "do_modrdn: database is read-only\n",
0, 0, 0 );
int srv_install( char* service, char * displayName, char* filename,
BOOL auto_start );
int srv_remove ( char* service, char* filename );
+DWORD svc_installed (LPTSTR lpszServiceName, LPTSTR lpszBinaryPathName);
+DWORD svc_running (LPTSTR lpszServiceName);
int main( int argc, LPTSTR *argv )
{
}
puts( "starting slapd..." );
- if ( !StartServiceCtrlDispatcher(DispatchTable) )
+ if (svc_installed(SERVICE_NAME, NULL) != 0
+ || svc_running(SERVICE_NAME) == 1
+ || StartServiceCtrlDispatcher(DispatchTable) != 0 )
{
is_NT_Service = 0;
ServiceMain( argc, argv );
Operation *op,
const char **text ));
+LIBSLAPD_F( int ) backend_check_referrals LDAP_P((
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ const char *dn,
+ const char *ndn ));
+
LIBSLAPD_F (int) backend_connection_init LDAP_P((Connection *conn));
LIBSLAPD_F (int) backend_connection_destroy LDAP_P((Connection *conn));
p = val->bv_val;
/* Ignore initial whitespace */
- while ( isspace( *p++ ) ) {
- /* EMPTY */ ;
+ while ( isspace( *p ) ) {
+ p++;
}
if( *p != '\0' ) {
*q++ = *p++;
/* Ignore the extra whitespace */
- while ( isspace( *p++ ) ) {
- /* EMPTY */ ;
+ while ( isspace( *p ) ) {
+ p++;
}
} else {
*q++ = *p++;
int i;
ber_len_t inlen=0;
+ /* Add up asserted input length */
if( sub->sa_initial ) {
inlen += sub->sa_initial->bv_len;
}
if( sub->sa_any ) {
- for(i=0; sub->sa_any[i]; i++) {
- inlen += sub->sa_final->bv_len;
+ for(i=0; sub->sa_any[i] != NULL; i++) {
+ inlen += sub->sa_any[i]->bv_len;
}
}
if( sub->sa_final ) {
inlen += sub->sa_final->bv_len;
}
- if( inlen > value->bv_len ) {
- match = 1;
- goto done;
- }
-
if( sub->sa_initial ) {
+ if( inlen > left.bv_len ) {
+ match = 1;
+ goto done;
+ }
+
match = strncmp( sub->sa_initial->bv_val, left.bv_val,
sub->sa_initial->bv_len );
}
if( sub->sa_final ) {
+ if( inlen > left.bv_len ) {
+ match = 1;
+ goto done;
+ }
+
match = strncmp( sub->sa_final->bv_val,
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
sub->sa_final->bv_len );
}
left.bv_len -= sub->sa_final->bv_len;
- inlen -= sub->sa_initial->bv_len;
+ inlen -= sub->sa_final->bv_len;
}
if( sub->sa_any ) {
char *p;
retry:
- if( inlen < left.bv_len ) {
+ if( inlen > left.bv_len ) {
/* not enough length */
match = 1;
goto done;
sub->sa_any[i]->bv_val,
sub->sa_any[i]->bv_len );
-
if( match != 0 ) {
+ left.bv_val++;
+ left.bv_len--;
goto retry;
}
left.bv_val += sub->sa_any[i]->bv_len;
left.bv_len -= sub->sa_any[i]->bv_len;
+ inlen -= sub->sa_any[i]->bv_len;
}
}
int i;
ber_len_t inlen=0;
+ /* Add up asserted input length */
if( sub->sa_initial ) {
inlen += sub->sa_initial->bv_len;
}
if( sub->sa_any ) {
- for(i=0; sub->sa_any[i]; i++) {
- inlen += sub->sa_final->bv_len;
+ for(i=0; sub->sa_any[i] != NULL; i++) {
+ inlen += sub->sa_any[i]->bv_len;
}
}
if( sub->sa_final ) {
inlen += sub->sa_final->bv_len;
}
- if( inlen > value->bv_len ) {
- match = 1;
- goto done;
- }
-
if( sub->sa_initial ) {
+ if( inlen > left.bv_len ) {
+ match = 1;
+ goto done;
+ }
+
match = strncasecmp( sub->sa_initial->bv_val, left.bv_val,
sub->sa_initial->bv_len );
left.bv_val += sub->sa_initial->bv_len;
left.bv_len -= sub->sa_initial->bv_len;
+ inlen -= sub->sa_initial->bv_len;
}
if( sub->sa_final ) {
+ if( inlen > left.bv_len ) {
+ match = 1;
+ goto done;
+ }
+
match = strncasecmp( sub->sa_final->bv_val,
&left.bv_val[left.bv_len - sub->sa_final->bv_len],
sub->sa_final->bv_len );
}
left.bv_len -= sub->sa_final->bv_len;
+ inlen -= sub->sa_final->bv_len;
}
if( sub->sa_any ) {
char *p;
retry:
- if( inlen < left.bv_len ) {
+ if( inlen > left.bv_len ) {
/* not enough length */
match = 1;
goto done;
sub->sa_any[i]->bv_val,
sub->sa_any[i]->bv_len );
-
if( match != 0 ) {
+ left.bv_val++;
+ left.bv_len--;
+
goto retry;
}
left.bv_val += sub->sa_any[i]->bv_len;
left.bv_len -= sub->sa_any[i]->bv_len;
+ inlen -= sub->sa_any[i]->bv_len;
}
}
}
static int
-NumericStringNormalize(
+numericStringNormalize(
Syntax *syntax,
struct berval *val,
struct berval **normalized )
p = val->bv_val;
/* Ignore initial whitespace */
- while ( isspace( *p++ ) ) {
- /* EMPTY */ ;
+ while ( isspace( *p ) ) {
+ p++;
}
if( *p != '\0' ) {
return LDAP_SUCCESS;
}
+static int
+check_time_syntax (struct berval *val,
+ int start,
+ int *parts)
+{
+ static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
+ static int mdays[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ char *p, *e;
+ int part, c, neg = 0;
+
+ if( val->bv_len == 0 )
+ return LDAP_INVALID_SYNTAX;
+
+ p = (char *)val->bv_val;
+ e = p + val->bv_len;
+
+ /* Ignore initial whitespace */
+ while ( ( p < e ) && isspace( *p ) ) {
+ p++;
+ }
+
+ if (e - p < 13 - (2 * start))
+ return LDAP_INVALID_SYNTAX;
+
+ for (part = 0; part < 9; part++)
+ parts[part] = 0;
+
+ for (part = start; part < 7; part++) {
+ c = *p;
+ if ((part == 6)
+ && (c == 'Z'
+ || c == '+'
+ || c == '-'))
+ {
+ part++;
+ break;
+ }
+ p++;
+ c -= '0';
+ if (p == e)
+ return LDAP_INVALID_SYNTAX;
+ if (c < 0 || c > 9)
+ return LDAP_INVALID_SYNTAX;
+ parts[part] = c;
+
+ c = *p++ - '0';
+ if (p == e)
+ return LDAP_INVALID_SYNTAX;
+ if (c < 0 || c > 9)
+ return LDAP_INVALID_SYNTAX;
+ parts[part] *= 10;
+ parts[part] += c;
+
+ if (part == 2 || part == 3)
+ parts[part]--;
+ if (parts[part] < 0)
+ return LDAP_INVALID_SYNTAX;
+ if (parts[part] > ceiling[part])
+ return LDAP_INVALID_SYNTAX;
+ }
+ if (parts[2] == 1) {
+ if (parts[3] > mdays[parts[2]])
+ return LDAP_INVALID_SYNTAX;
+ if (parts[1] & 0x03) {
+ /* FIXME: This is an incomplete leap-year
+ * check that fails in 2100, 2200, 2300,
+ * 2500, 2600, 2700, ...
+ */
+ if (parts[3] > mdays[parts[2]] - 1)
+ return LDAP_INVALID_SYNTAX;
+ }
+ }
+ c = *p++;
+ if (c == 'Z') {
+ /* all done */
+ } else if (c != '+' && c != '-') {
+ return LDAP_INVALID_SYNTAX;
+ } else {
+ if (c == '-')
+ neg = 1;
+ if (p > e - 4)
+ return LDAP_INVALID_SYNTAX;
+ for (part = 7; part < 9; part++) {
+ c = *p++ - '0';
+ if (c < 0 || c > 9)
+ return LDAP_INVALID_SYNTAX;
+ parts[part] = c;
+
+ c = *p++ - '0';
+ if (c < 0 || c > 9)
+ return LDAP_INVALID_SYNTAX;
+ parts[part] *= 10;
+ parts[part] += c;
+ if (parts[part] < 0 || parts[part] > ceiling[part])
+ return LDAP_INVALID_SYNTAX;
+ }
+ }
+
+ /* Ignore trailing whitespace */
+ while ( ( p < e ) && isspace( *p ) ) {
+ p++;
+ }
+ if (p != e)
+ return LDAP_INVALID_SYNTAX;
+
+ if (neg == 0) {
+ parts[4] += parts[7];
+ parts[5] += parts[8];
+ for (part = 7; --part > 0; ) {
+ if (part != 3)
+ c = ceiling[part];
+ else {
+ /* FIXME: This is an incomplete leap-year
+ * check that fails in 2100, 2200, 2300,
+ * 2500, 2600, 2700, ...
+ */
+ c = mdays[parts[2]];
+ if (parts[2] == 1)
+ c--;
+ }
+ if (parts[part] > c) {
+ parts[part] -= c + 1;
+ parts[part - 1]++;
+ }
+ }
+ } else {
+ parts[4] -= parts[7];
+ parts[5] -= parts[8];
+ for (part = 7; --part > 0; ) {
+ if (part != 3)
+ c = ceiling[part];
+ else {
+ /* FIXME: This is an incomplete leap-year
+ * check that fails in 2100, 2200, 2300,
+ * 2500, 2600, 2700, ...
+ */
+ c = mdays[(parts[2] - 1) % 12];
+ if (parts[2] == 2)
+ c--;
+ }
+ if (parts[part] < 0) {
+ parts[part] += c + 1;
+ parts[part - 1]--;
+ }
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static int
+utcTimeNormalize(
+ Syntax *syntax,
+ struct berval *val,
+ struct berval **normalized )
+{
+ struct berval *out;
+ int parts[9], rc;
+
+ rc = check_time_syntax(val, 1, parts);
+ if (rc != LDAP_SUCCESS) {
+ return rc;
+ }
+
+ *normalized = NULL;
+ out = ch_malloc( sizeof(struct berval) );
+ if( out == NULL )
+ return LBER_ERROR_MEMORY;
+
+ out->bv_val = ch_malloc( 14 );
+ if ( out->bv_val == NULL ) {
+ ch_free( out );
+ return LBER_ERROR_MEMORY;
+ }
+
+ sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
+ parts[1], parts[2] + 1, parts[3] + 1,
+ parts[4], parts[5], parts[6] );
+ out->bv_len = 13;
+ *normalized = out;
+
+ return LDAP_SUCCESS;
+}
+
+static int
+utcTimeValidate(
+ Syntax *syntax,
+ struct berval *in )
+{
+ int parts[9];
+
+ return check_time_syntax(in, 1, parts);
+}
+
+static int
+generalizedTimeNormalize(
+ Syntax *syntax,
+ struct berval *val,
+ struct berval **normalized )
+{
+ struct berval *out;
+ int parts[9], rc;
+
+ rc = check_time_syntax(val, 0, parts);
+ if (rc != LDAP_SUCCESS) {
+ return rc;
+ }
+
+ *normalized = NULL;
+ out = ch_malloc( sizeof(struct berval) );
+ if( out == NULL )
+ return LBER_ERROR_MEMORY;
+
+ out->bv_val = ch_malloc( 16 );
+ if ( out->bv_val == NULL ) {
+ ch_free( out );
+ return LBER_ERROR_MEMORY;
+ }
+
+ sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
+ parts[0], parts[1], parts[2] + 1, parts[3] + 1,
+ parts[4], parts[5], parts[6] );
+ out->bv_len = 15;
+ *normalized = out;
+
+ return LDAP_SUCCESS;
+}
+
+static int
+generalizedTimeValidate(
+ Syntax *syntax,
+ struct berval *in )
+{
+ int parts[9];
+
+ return check_time_syntax(in, 0, parts);
+}
+
struct syntax_defs_rec {
char *sd_desc;
int sd_flags;
#define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
#define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
+#define faxNumberNormalize numericStringNormalize
+#define phoneNumberNormalize numericStringNormalize
+#define telexNumberNormalize numericStringNormalize
+
struct syntax_defs_rec syntax_defs[] = {
{"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
- 0, blobValidate, NULL, NULL},
+ 0, IA5StringValidate, faxNumberNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
- 0, NULL, NULL, NULL},
+ 0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
{"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
- 0, IA5StringValidate, NumericStringNormalize, NULL},
+ 0, IA5StringValidate, numericStringNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
X_BINARY X_NOT_H_R ")",
SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
- 0, blobValidate, NULL, NULL},
+ 0, IA5StringValidate, phoneNumberNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
- 0, NULL, NULL, NULL},
+ 0, IA5StringValidate, telexNumberNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
- 0, NULL, NULL, NULL},
+ 0, utcTimeValidate, utcTimeNormalize, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
/* OpenLDAP Experimental Syntaxes */
{"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
- 0, NULL, NULL, NULL},
+ 0, IA5StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */, NULL, NULL},
{"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
0, NULL, NULL, NULL},
{"( 1.3.6.1.4.1.4203.666.2.3 DESC 'OpenLDAP void' " X_HIDE ")" ,
#define presentationAddressMatch NULL
#define uniqueMemberMatch NULL
#define protocolInformationMatch NULL
-#define generalizedTimeMatch NULL
-#define generalizedTimeOrderingMatch NULL
+#define generalizedTimeMatch caseExactIA5Match
+#define generalizedTimeOrderingMatch caseExactIA5Match
#define integerFirstComponentMatch NULL
#define objectIdentifierFirstComponentMatch NULL
#include "ldap_pvt.h"
#include "slap.h"
-
int
do_search(
Connection *conn, /* where to send results */
Operation *op /* info about the op to which we're responding */
-)
-{
+) {
int i;
ber_int_t scope, deref, attrsonly;
ber_int_t sizelimit, timelimit;
/* make sure this backend recongizes critical controls */
rc = backend_check_controls( be, conn, op, &text ) ;
-
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto return_results;
}
+ /* check for referrals */
+ rc = backend_check_referrals( be, conn, op, base, nbase );
+ if ( rc != LDAP_SUCCESS ) {
+ goto return_results;
+ }
+
/* deref the base if needed */
nbase = suffix_alias( be, nbase );
#define be_extended bd_info->bi_extended
#define be_release bd_info->bi_entry_release_rw
+#define be_chk_referrals bd_info->bi_chk_referrals
#define be_group bd_info->bi_acl_group
#define be_controls bd_info->bi_controls
/* Auxilary Functions */
int (*bi_entry_release_rw) LDAP_P((BackendDB *bd, Entry *e, int rw));
+ int (*bi_chk_referrals) LDAP_P((BackendDB *bd,
+ struct slap_conn *c, struct slap_op *o,
+ const char *dn, const char *ndn,
+ const char **text ));
+
int (*bi_acl_group) LDAP_P((Backend *bd,
Entry *e, const char *bdn, const char *edn,
ObjectClass *group_oc,
usage(const char *s)
{
fprintf(stderr,
- "Usage: %s [options] dn\n"
+ "Usage: %s [options]\n"
" -h hash\tpassword scheme\n"
" -s secret\tnew password\n"
" -v\t\tincrease verbosity\n"
struct berval passwd;
struct berval *hash = NULL;
- if (argc == 1)
- usage (argv[0]);
-
while( (i = getopt( argc, argv,
"d:h:s:v" )) != EOF )
{
if( newpw == NULL ) {
/* prompt for new password */
char *cknewpw;
- newpw = strdup(getpass("New password: "));
- cknewpw = getpass("Re-enter new password: ");
+ newpw = strdup(getpassphrase("New password: "));
+ cknewpw = getpassphrase("Re-enter new password: ");
if( strncmp( newpw, cknewpw, strlen(newpw) )) {
fprintf( stderr, "passwords do not match\n" );
+++ /dev/null
-# $OpenLDAP$
-#
-# master slapd config -- for testing
-#
-include ./data/slapd.at.conf
-include ./data/slapd.oc.conf
-schemacheck off
-pidfile ./test-db/slapd.pid
-argsfile ./test-db/slapd.args
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-backend bdb2
-home ./test-db
-
-database bdb2
-cachesize 0
-suffix "o=University of Michigan, c=US"
-directory ./test-db
-rootdn "cn=Manager, o=University of Michigan, c=US"
-rootpw secret
-index cn,sn,uid pres,eq,approx
-index default none
-lastmod on
-defaultaccess none
-
-access to attr=objectclass
- by * read
-
-access to filter="objectclass=person" attr=userpassword
- by self write
- by anonymous auth
- by * none
-
-access to dn=".*,ou=Alumni Association,ou=People,o=University of Michigan,c=US"
- by dn=".*,o=University of Michigan,c=US" read
- by anonymous auth
- by * none
-
-access to attr=member
- by dnattr=member selfwrite
- by * read
-
-access to filter="objectclass=groupofnames"
- by dn="Bjorn Jensen,ou=Information Technology Division,ou=People,o=University of Michigan,c=US" write
- by * read
-
-access to * by * read
+++ /dev/null
-# $OpenLDAP$
-#
-# master slapd config -- for testing
-#
-include ./data/slapd.at.conf
-include ./data/slapd.oc.conf
-schemacheck on
-pidfile ./test-db/slapd.pid
-argsfile ./test-db/slapd.args
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-backend bdb2
-home ./test-db
-mpoolsize 21000000
-
-database bdb2
-suffix "o=University of Michigan, c=US"
-directory ./test-db
-rootdn "cn=Manager, o=University of Michigan, c=US"
-rootpw secret
-index cn,sn,uid pres,eq,approx
-index default none
-lastmod on
+++ /dev/null
-# $OpenLDAP$
-#
-# master slapd config -- for testing
-#
-include ../servers/slapd/schema/others_nis.at.conf
-include ../servers/slapd/schema/others_nis.oc.conf
-include ../servers/slapd/schema/nis.at.conf
-include ../servers/slapd/schema/nis.oc.conf
-include ../servers/slapd/schema/internet_mail.at.conf
-include ../servers/slapd/schema/internet_mail.oc.conf
-schemacheck on
-pidfile ./test-db/slapd.pid
-argsfile ./test-db/slapd.args
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-backend bdb2
-home ./test-db
-mpoolsize 21000000
-
-database bdb2
-cachesize 4
-suffix "o=SGI, c=US"
-directory ./test-db
-rootdn "cn=Manager, o=SGI, c=US"
-rootpw secret
-index uid pres,eq,approx
-index gidNumber pres,eq,approx
-index uidNumber pres,eq,approx
-index cn pres,eq,approx
-index memberUid pres,eq,approx
-index macAddress pres,eq,approx
-index ipServiceProtocol pres,eq,approx
-index ipServicePort pres,eq,approx
-index oncRpcNumber pres,eq,approx
-index ipHostNumber pres,eq,approx
-index ipNetworkNumber pres,eq,approx
-index ipProtocolNumber pres,eq,approx
-index default none
-lastmod on
+++ /dev/null
-# $OpenLDAP$
-#
-# master slapd config -- for testing
-#
-include ./data/slapd.at.conf
-include ./data/slapd.oc.conf
-schemacheck off
-pidfile ./test-db/slapd.pid
-argsfile ./test-db/slapd.args
-
-# password-hash {md5}
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-database ldbm
-cachesize 0
-suffix "o=University of Michigan, c=US"
-directory ./test-db
-rootdn "cn=Manager, o=University of Michigan, c=US"
-rootpw secret
-index cn,sn,uid pres,eq,approx
-index default none
-lastmod on
-defaultaccess none
-
-#
-# normal installations should protect root dse,
-# cn=monitor, cn=schema, and cn=config
-#
-
-access to attr=userpassword
- by anonymous auth
- by self write
-
-access to *
- by self write
- by * read
+++ /dev/null
-# $OpenLDAP$
-#
-# slave slapd config -- for default referral testing
-#
-include ./data/slapd.at.conf
-include ./data/slapd.oc.conf
-schemacheck off
-pidfile ./test-repl/slapd.pid
-argsfile ./test-repl/slapd.args
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-referral "ldap://localhost:9009/"
-
-backend bdb2
-home ./test-db
-
-database bdb2
-cachesize 0
-suffix "o=University of Mich, c=US"
-directory ./test-repl
-rootdn "cn=Manager, o=University of Mich, c=US"
-rootpw secret
-index cn,sn,uid pres,eq,approx
-index default none
-# index default pres,eq,approx
-lastmod on
+++ /dev/null
-# $OpenLDAP$
-#
-# master slapd config -- for testing of replication
-#
-include ./data/slapd.at.conf
-include ./data/slapd.oc.conf
-schemacheck off
-pidfile ./test-db/slapd.pid
-argsfile ./test-db/slapd.args
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-backend bdb2
-home ./test-db
-
-database bdb2
-cachesize 0
-suffix "o=University of Michigan, c=US"
-directory ./test-db
-rootdn "cn=Manager, o=University of Michigan, c=US"
-rootpw secret
-index cn,sn,uid pres,eq,approx
-index default none
-# index default pres,eq,approx
-lastmod on
-
-replogfile ./test-db/slapd.replog
-
-replica host=localhost:9010
- binddn="cn=Replica, o=University of Michigan, c=US"
- bindmethod=simple
- credentials=secret
+++ /dev/null
-# $OpenLDAP$
-#
-# master slapd config -- for testing of replication
-#
-include ./data/slapd.at.conf
-include ./data/slapd.oc.conf
-schemacheck off
-pidfile ./test-repl/slapd.pid
-argsfile ./test-repl/slapd.args
-
-referral "ldap://localhost:9009/"
-
-#######################################################################
-# ldbm database definitions
-#######################################################################
-
-backend bdb2
-home ./test-repl
-
-database bdb2
-cachesize 0
-suffix "o=University of Michigan, c=US"
-directory ./test-repl
-rootdn "cn=Replica, o=University of Michigan, c=US"
-rootpw secret
-updatedn "cn=Replica, o=University of Michigan, c=US"
-updateref "ldap://localhost:9009/o=University%20of%20Michigan,c=US"
-index cn,sn,uid pres,eq,approx
-index default none
-# index default pres,eq,approx
-lastmod on