Individual Submission C. Morris Internet Draft Novell Inc. Document: draft-morris-ldap-c-api-schema-00.txt October 2001 Category: Informational Schema Functions for the LDAP C API 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. Abstract The following defines a standard API to ease the reading and modifying of Schema using the LDAP C API [CLDAP], a work in progress. It abstracts finding, reading, parsing, and modifying of schema definitions in an LDAP directory. Comparable functionality exists in the LDAP Java API [JLDAP], also a work in progress. Conventions used in this document The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC-2119. (OUT) indicates a parameter that returns a value. All other parameter definitions are assumed to be input parameters. Morris Informational Schema functions for the LDAP C API October 2001 Table of Contents 1 Introduction.......................................................4 2 LDAP Schema Structures.............................................4 2.1 LDAPSchema.......................................................4 2.2 LDAPSchemaElement................................................4 2.3 LDAPSchemaMod....................................................4 3 Macros for Schema definitions......................................5 3.1 Schema element types.............................................5 3.2 LDAP_SCHEMA_ATTRIBUTE_TYPE field names...........................5 3.2.1 LDAP_SCHEMA_OID................................................6 3.2.2 LDAP_SCHEMA_DESCRIPTION........................................6 3.2.3 LDAP_SCHEMA_NAMES..............................................6 3.2.4 LDAP_SCHEMA_OBSOLETE...........................................6 3.2.5 LDAP_SCHEMA_SUPERIOR...........................................6 3.2.6 LDAP_SCHEMA_EQUALITY...........................................6 3.2.7 LDAP_SCHEMA_ORDERING...........................................6 3.2.8 LDAP_SCHEMA_SUBSTRING..........................................6 3.2.9 LDAP_SCHEMA_SYNTAX_OID.........................................7 3.2.10 LDAP_SCHEMA_SINGLE_VALUED.....................................7 3.2.11 LDAP_SCHEMA_COLLECTIVE........................................7 3.2.12 LDAP_SCHEMA_NO_USER_MOD.......................................7 3.2.13 LDAP_SCHEMA_USAGE.............................................7 3.2.13.1 LDAP_SCHEMA_USER_APP........................................7 3.2.13.2 LDAP_SCHEMA_DIRECTORY_OP....................................8 3.2.13.3 LDAP_SCHEMA_DISTRIBUTED_OP..................................8 3.2.13.4 LDAP_SCHEMA_DSA_OP..........................................8 3.3 LDAP_SCHEMA_OBJECT_CLASS field names.............................8 3.3.1 LDAP_SCHEMA_OID................................................8 3.3.2 LDAP_SCHEMA_DESCRIPTION........................................8 3.3.3 LDAP_SCHEMA_NAMES..............................................8 3.3.4 LDAP_SCHEMA_OBSOLETE...........................................8 3.3.5 LDAP_SCHEMA_SUPERIOR...........................................9 3.3.6 LDAP_SCHEMA_MUST_ATTRIBUTES....................................9 3.3.7 LDAP_SCHEMA_MAY_ATTRIBUTES.....................................9 3.3.8 LDAP_SCHEMA_TYPE_ABSTRACT......................................9 3.3.9 LDAP_SCHEMA_TYPE_STRUCTURAL....................................9 3.3.10 LDAP_SCHEMA_TYPE_AUXILIARY....................................9 3.4 LDAP_SCHEMA_MATCHING_RULE field names............................9 3.4.1 LDAP_SCHEMA_OID...............................................10 3.4.2 LDAP_SCHEMA_DESCRIPTION.......................................10 3.4.3 LDAP_SCHEMA_NAMES.............................................10 3.4.4 LDAP_SCHEMA_OBSOLETE..........................................10 3.4.5 LDAP_SCHEMA_SYNTAX_OID........................................10 3.5 LDAP_SCHEMA_MATCHING_RULE_USE field names.......................10 3.5.1 LDAP_SCHEMA_OID...............................................10 3.5.2 LDAP_SCHEMA_DESCRIPTION.......................................10 3.5.3 LDAP_SCHEMA_NAMES.............................................11 3.5.4 LDAP_SCHEMA_OBSOLETE..........................................11 3.5.5 LDAP_SCHEMA_APPLIES...........................................11 3.6 LDAP_SCHEMA_NAME_FORM field names...............................11 3.6.1 LDAP_SCHEMA_OID...............................................11 3.6.2 LDAP_SCHEMA_DESCRIPTION.......................................11 Morris Informational 2 Schema functions for the LDAP C API October 2001 3.6.3 LDAP_SCHEMA_NAMES.............................................11 3.6.4 LDAP_SCHEMA_OBSOLETE..........................................11 3.6.5 LDAP_SCHEMA_NAME_FORM_OBJECTS.................................12 3.6.6 LDAP_SCHEMA_MUST_ATTRIBUTES...................................12 3.6.7 LDAP_SCHEMA_MAY_ATTRIBUTES....................................12 3.7 LDAP_SCHEMA_SYNTAX field names..................................12 3.7.1 LDAP_SCHEMA_OID...............................................12 3.7.2 LDAP_SCHEMA_DESCRIPTION.......................................12 3.8 LDAP_SCHEMA_DIT_CONTENT_RULE field names........................12 3.8.1 LDAP_SCHEMA_OID...............................................12 3.8.2 LDAP_SCHEMA_DESCRIPTION.......................................13 3.8.3 LDAP_SCHEMA_NAMES.............................................13 3.8.4 LDAP_SCHEMA_OBSOLETE..........................................13 3.8.5 LDAP_SCHEMA_AUX_CLASSES.......................................13 3.8.6 LDAP_SCHEMA_MUST_ATTRIBUTES...................................13 3.8.7 LDAP_SCHEMA_MAY_ATTRIBUTES....................................13 3.8.8 LDAP_SCHEMA_NOT_ATTRIBUTES....................................13 3.9 LDAP_SCHEMA_DIT_STRUCTURE_RULE field names......................14 3.9.1 LDAP_SCHEMA_RULE_ID...........................................14 3.9.2 LDAP_SCHEMA_DESCRIPTION.......................................14 3.9.3 LDAP_SCHEMA_NAMES.............................................14 3.9.4 LDAP_SCHEMA_OBSOLETE..........................................14 3.9.5 LDAP_SCHEMA_NAME_FORM_OID.....................................14 3.9.6 LDAP_SCHEMA_SCHEMA_SUPERIOR...................................14 4 Functions.........................................................14 4.1 Initializing and freeing LDAPSchema handles.....................14 4.1.1 ldap_schema_fetch.............................................14 4.1.2 ldap_schema_free..............................................15 4.2 Retrieving handles to individual schema elements................15 4.2.1 ldap_schema_get_by_name.......................................15 4.2.2 ldap_schema_get_count.........................................16 4.2.3 ldap_schema_get_by_index......................................16 4.3 Reading fields of schema elements...............................17 4.3.1 ldap_schema_get_field_names...................................17 4.3.2 ldap_schema_get_field_values..................................17 4.4 Adding, modifying, and deleting.................................17 4.4.1 ldap_schema_add...............................................17 4.4.2 ldap_schema_modify............................................18 4.4.3 ldap_schema_delete............................................19 5 Sample Code.......................................................20 6 Security Considerations...........................................23 7 References........................................................23 8 Acknowledgments...................................................23 9 Author's Address..................................................23 Morris Informational 3 Schema functions for the LDAP C API October 2001 1 Introduction One main structure represents the entire schema of a directory, LDAPSchema. The directory schema is located and parsed into this structure. Using this structure, a user locates an individual schema definition, in the form of the structure LDAPSchemaElement. These structures are explained in section 2. Each LDAPSchemaElement can represent 8 different types of schema definitions. These types are listed in section 3. This API presents the definition of a schema element as a list of fields. Each field is identified by a field name and may have an associated value. Section 3 defines macros to be used for field names. Adding, modifying and deleting schema definitions are performed directly to the directory and can be reflected in an LDAPSchema structure. The [CLDAP] API requires a macro be defined to identify additional API features. Thus implementations of this API MUST have the following macro defined: #define LDAP_API_FEATURE_SCHEMA_UTIL 100 2 LDAP Schema Structures 2.1 LDAPSchema typedef struct ldap_schema LDAPSchema; LDAPSchema is an opaque structure that contains all schema definitions. It represents a local copy of an LDAP Directory schema. This structure is needed to locate, modify, and delete schema definitions. 2.2 LDAPSchemaElement typedef struct ldap_schema_element LDAPSchemaElement; LDAPSchemaElement is an opaque structure that contains a single schema definition. An LDAPSchemaElement represents one of eight possible schema definition types explained in rfc2252 [ATTR], and are described in Section 3.1 of this document. 2.3 LDAPSchemaMod typedef struct ldap_schema_mod { int op; /* Uses the same #define's as LDAPMod */ char *fieldName; /* name of the field to modify */ char **values; /* Values of the field. */ } LDAPSchemaMod; Morris Informational 4 Schema functions for the LDAP C API October 2001 LDAPSchemaMod contains the definition of one field in a schema definition. A NULL terminated array of LDAPSchemaMod structures represent all fields to be included in a new definition, or all fields to be modified in an existing definition. A field value can be added, replaced or deleted. op Indicates whether the values are to add to, replace, or delete from the existing values of a field. Uses the definitions in the [CLDAP] API: LDAP_MOD_ADD, LDAP_MOD_DELETE, and LDAP_MOD_REPLACE. fieldName Identifies the name of the field. Macros for standard field names from rfc2252[ATTR] are defined in section 3.2. values A NULL terminated array of strings, containing the values that correspond to the field name. 3 Macros for Schema definitions. The following macros are derived from the definitions in rfc2252 [ATTR]. Section 3.1 lists the types of schema elements that can be defined. Sections 3.2 through 3.9 list the field names valid in a specific type of a schema element. Addition fields to those defined in these sections MAY be defined. Vendor specific or experimental field names start with 'X-' or 'x-', and MAY be supported. 3.1 Schema element types. The following define macros used to identify the type of definition represented by an LDAPSchemaElement structure. #define LDAP_SCHEMA_ATTRIBUTE_TYPE 1 #define LDAP_SCHEMA_OBJECT_CLASS 2 #define LDAP_SCHEMA_MATCHING_RULE 3 #define LDAP_SCHEMA_MATCHING_RULE_USE 4 #define LDAP_SCHEMA_NAME_FORM 5 #define LDAP_SCHEMA_SYNTAX 6 #define LDAP_SCHEMA_DIT_CONTENT_RULE 7 #define LDAP_SCHEMA_DIT_STRUCTURE_RULE 8 Valid fields in a schema element depend on the type of definition it represents. The following sections contain macros for valid field names for each schema element type. 3.2 LDAP_SCHEMA_ATTRIBUTE_TYPE field names. The following define attribute type specific fields as defined in rfc2252[ATTR]. Morris Informational 5 Schema functions for the LDAP C API October 2001 3.2.1 LDAP_SCHEMA_OID #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. 3.2.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.2.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.2.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. 3.2.5 LDAP_SCHEMA_SUPERIOR #define LDAP_SCHEMA_SUPERIOR "SUP" Defines the name of the attribute from which this attribute is derived. 3.2.6 LDAP_SCHEMA_EQUALITY #define LDAP_SCHEMA_EQUALITY "EQUALITY" Defines the Object identifier of the Matching rule used for an equality comparison of this attribute. 3.2.7 LDAP_SCHEMA_ORDERING #define LDAP_SCHEMA_ORDERING "ORDERING" Defines the Object identifier of the Matching rule used for an ordering-collating comparison of this attribute. 3.2.8 LDAP_SCHEMA_SUBSTRING #define LDAP_SCHEMA_SUBSTRING "SUBSTR" Morris Informational 6 Schema functions for the LDAP C API October 2001 Defines the Object identifier of the Matching rule used for a substring comparison of this attribute. 3.2.9 LDAP_SCHEMA_SYNTAX_OID #define LDAP_SCHEMA_SYNTAX_OID "SYNTAX" Defines the Object identifier of the syntax that will be used for this attribute. 3.2.10 LDAP_SCHEMA_SINGLE_VALUED #define LDAP_SCHEMA_SINGLE_VALUED "SINGLE-VALUE" Defines whether or not this attribute is multi-valued or not. This field has no value. If the field name is present the attribute is single valued, otherwise it is multi-valued. 3.2.11 LDAP_SCHEMA_COLLECTIVE #define LDAP_SCHEMA_COLLECTIVE "COLLECTIVE" Defines whether or not this attribute is collective, meaning all instances of an object with this attribute will have the same value for this attribute. This field has no value. If the field name is present the attribute is collective, otherwise it is not. 3.2.12 LDAP_SCHEMA_NO_USER_MOD #define LDAP_SCHEMA_NO_USER_MOD "NO-USER-MODIFICATION" Defines whether or not a user can modify this attribute. This field has no value. If the field name is present the attribute is not modifiable, otherwise it is modifiable. 3.2.13 LDAP_SCHEMA_USAGE #define LDAP_SCHEMA_USAGE "USAGE" Defines whether this attribute is used by a user application, a directory operation, a distributed operation or a per-DSA (Directory Service Agent) operation. The following define strings for the value of this field. 3.2.13.1 LDAP_SCHEMA_USER_APP #define LDAP_SCHEMA_USER_APP "userApplications" If the LDAP_SCHEMA_USAGE field name has this value then the attribute is used by an application independent of the directory server. Morris Informational 7 Schema functions for the LDAP C API October 2001 3.2.13.2 LDAP_SCHEMA_DIRECTORY_OP #define LDAP_SCHEMA_DIRECTORY_OP "directoryOperation" If the LDAP_SCHEMA_USAGE field name has this value then the directory uses the defined attribute. 3.2.13.3 LDAP_SCHEMA_DISTRIBUTED_OP #define LDAP_SCHEMA_DISTRIBUTED_OP "distributedOperation" If the LDAP_SCHEMA_USAGE field name has this value then the attribute is share between DSAs, Directory Server Agents. 3.2.13.4 LDAP_SCHEMA_DSA_OP #define LDAP_SCHEMA_DSA_OP "dSAOperation" If the LDAP_SCHEMA_USAGE field name has this value then the attribute can be unique for each DSA, Directory Server Agent. 3.3 LDAP_SCHEMA_OBJECT_CLASS field names The following define ObjectClass specific fields. 3.3.1 LDAP_SCHEMA_OID #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. 3.3.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.3.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.3.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. Morris Informational 8 Schema functions for the LDAP C API October 2001 3.3.5 LDAP_SCHEMA_SUPERIOR #define LDAP_SCHEMA_SUPERIOR "SUP" Defines the objectClasses from which this objectClass is derived. 3.3.6 LDAP_SCHEMA_MUST_ATTRIBUTES #define LDAP_SCHEMA_MUST_ATTRIBUTES "MUST" Defines all attributes that must be defined in an instance of this object. 3.3.7 LDAP_SCHEMA_MAY_ATTRIBUTES #define LDAP_SCHEMA_MAY_ATTRIBUTES "MAY" Defines all attributes that may be defined in an instance of this object. 3.3.8 LDAP_SCHEMA_TYPE_ABSTRACT #define LDAP_SCHEMA_TYPE_ABSTRACT "ABSTRACT" Defines that this object is abstract. An abstract object can be derived from but not instantiated. This field name does not have a value. This field name cannot be present if LDAP_SCHEMA_TYPE_STRUCTURAL or LDAP_SCHEMA_TYPE_AUXILIARY is present. 3.3.9 LDAP_SCHEMA_TYPE_STRUCTURAL #define LDAP_SCHEMA_TYPE_STRUCTURAL "STRUCTURAL" Defines that this object is structural. A structural object can be derived from and instantiated. This field name does not have a value. This field name cannot be present if LDAP_SCHEMA_TYPE_ABSTRACT or LDAP_SCHEMA_TYPE_AUXILIARY is present. 3.3.10 LDAP_SCHEMA_TYPE_AUXILIARY #define LDAP_SCHEMA_TYPE_AUXILIARY "AUXILIARY" Defines that this object is auxiliary. An auxiliary object can be associated with any instantiated object. This field name does not have a value. This field name cannot be present if LDAP_SCHEMA_TYPE_ABSTRACT or LDAP_SCHEMA_TYPE_STRUCTURAL is present. 3.4 LDAP_SCHEMA_MATCHING_RULE field names The following define Matching Rule specific fields. Morris Informational 9 Schema functions for the LDAP C API October 2001 3.4.1 LDAP_SCHEMA_OID #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. 3.4.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.4.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.4.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. 3.4.5 LDAP_SCHEMA_SYNTAX_OID #define LDAP_SCHEMA_SYNTAX_OID "SYNTAX" Defines the syntax of the Matching Rule. Only one value can exist for this field name. 3.5 LDAP_SCHEMA_MATCHING_RULE_USE field names The following define Matching Rule Use specific fields. 3.5.1 LDAP_SCHEMA_OID #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. Note: The LDAP_SCHEMA_OID in the definition of a Matching Rule identifies a Matching Rule, not the Matching Rule use definition. 3.5.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" Morris Informational 10 Schema functions for the LDAP C API October 2001 This field is a string definition of the schema element. This field has only one value. 3.5.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.5.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. 3.5.5 LDAP_SCHEMA_APPLIES #define LDAP_SCHEMA_APPLIES "APPLIES" Defines the attributes that the Matching Rule applies to. This field is required for Matching Rule Use definitions. 3.6 LDAP_SCHEMA_NAME_FORM field names The following define Name Form specific fields. 3.6.1 LDAP_SCHEMA_OID #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. 3.6.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.6.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.6.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Morris Informational 11 Schema functions for the LDAP C API October 2001 Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. 3.6.5 LDAP_SCHEMA_NAME_FORM_OBJECTS #define LDAP_SCHEMA_NAME_FORM_OBJECTS "OC" Defines the Object Classes to which this Name Form applies. This field is required for name forms. 3.6.6 LDAP_SCHEMA_MUST_ATTRIBUTES #define LDAP_SCHEMA_MUST_ATTRIBUTES "MUST" Defines the mandatory attributes to which this name form applies. This field is required for name forms. 3.6.7 LDAP_SCHEMA_MAY_ATTRIBUTES #define LDAP_SCHEMA_MAY_ATTRIBUTES "MAY" Defines the optional attributes to which this name form applies. 3.7 LDAP_SCHEMA_SYNTAX field names This schema element is used to discover the known set of syntaxes in effect for the subschema. Only LDAP_SCHEMA_OID, LDAP_SCHEMA_DESCRIPTION, and any server specific 'X-' fields are described for syntax [ATTR]. 3.7.1 LDAP_SCHEMA_OID #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. 3.7.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.8 LDAP_SCHEMA_DIT_CONTENT_RULE field names The following sections define DIT (Directory Information Tree) content Rule specific fields. LDAP_SCHEMA_OID identifies a Structural Object Class and is the only required field. 3.8.1 LDAP_SCHEMA_OID Morris Informational 12 Schema functions for the LDAP C API October 2001 #define LDAP_SCHEMA_OID "OID" Object identifier of the schema element. This field has only one value. 3.8.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.8.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.8.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. 3.8.5 LDAP_SCHEMA_AUX_CLASSES #define LDAP_SCHEMA_AUX_CLASSES "AUX" Defines the auxiliary classes that can be applied to a structural object Class. 3.8.6 LDAP_SCHEMA_MUST_ATTRIBUTES #define LDAP_SCHEMA_MUST_ATTRIBUTES "MUST" Defines the mandatory attributes that a structural object class can obtain from an auxiliary class. 3.8.7 LDAP_SCHEMA_MAY_ATTRIBUTES #define LDAP_SCHEMA_MAY_ATTRIBUTES "MAY" Defines the optional attributes that a structural object class can obtain from an auxiliary class. 3.8.8 LDAP_SCHEMA_NOT_ATTRIBUTES #define LDAP_SCHEMA_NOT_ATTRIBUTES "NOT" Defines the attributes that a structural object class cannot obtain from an auxiliary class. Morris Informational 13 Schema functions for the LDAP C API October 2001 3.9 LDAP_SCHEMA_DIT_STRUCTURE_RULE field names The following sections define fields specific to DIT Structure Rules. Note that LDAP_SCHEMA_OID is not valid for this structure. The rule is identified by an integer, LDAP_SCHEMA_RULE_ID. 3.9.1 LDAP_SCHEMA_RULE_ID #define LDAP_SCHEMA_RULE_ID "RULEID" Defines the integer identifier for this rule. 3.9.2 LDAP_SCHEMA_DESCRIPTION #define LDAP_SCHEMA_DESCRIPTION "DESC" This field is a string definition of the schema element. This field has only one value. 3.9.3 LDAP_SCHEMA_NAMES #define LDAP_SCHEMA_NAMES "NAME" Defines all names used to identify the schema element. 3.9.4 LDAP_SCHEMA_OBSOLETE #define LDAP_SCHEMA_OBSOLETE "OBSOLETE" Defines whether this schema definition is still in use. This field has no value. If the field name is present, the definition is obsolete; otherwise the definition is still valid. 3.9.5 LDAP_SCHEMA_NAME_FORM_OID #define LDAP_SCHEMA_NAME_FORM_OID "FORM" Defines the Name Form that applies to this structure rule. 3.9.6 LDAP_SCHEMA_SCHEMA_SUPERIOR #define LDAP_SCHEMA_SUPERIOR "SUP" Defines all structure rules that this rule derives from. 4 Functions 4.1 Initializing and freeing LDAPSchema handles. 4.1.1 ldap_schema_fetch int ldap_schema_fetch (LDAP *ld, LDAPSchema **schema) Morris Informational 14 Schema functions for the LDAP C API October 2001 A call to ldap_schema_fetch will connect to a directory and locate the SubSchemaSubEntry. It allocates an LDAPSchema structure and populates it with all available schema definitions. Parameters are: ld LDAP session handle. schema (OUT) Address of a handle to LDAPSchema, contains a local copy of the entire directory schema. Return value is an LDAP result code. 4.1.2 ldap_schema_free int ldap_schema_free (LDAPSchema *schema) The function ldap_schema_free() will free the memory allocated to an LDAPSchema handle. For every handle created by ldap_schema_fetch, ldap_schema_free must be called to free the memory. Parameters are: schema Handle to a local copy of directory schema. Return value is an LDAP result code. 4.2 Retrieving handles to individual schema elements 4.2.1 ldap_schema_get_by_name int ldap_schema_get_by_name (LDAPSchema *schema, char* nameOrOid, int elementType, LDAPSchemaElement **element) ldap_schema_get_by_name retrieves a handle to a schema element, identified by its type and either a name or oid. The returned handle to an LDAPSchemaElement structure, 'element', is a pointer to memory within the LDAPSchema structure, 'schema'. Therefore if 'schema' changes or is freed, 'element' may also change, or become invalid. Likewise, if the user frees or tampers with 'element', 'schema' may become corrupted. Parameters are: schema A handle to the schema of an LDAP directory. nameOrOid Name or oid of the schema element requested. elementType Type of element requested. Use the definitions listed in Section 3.1. Morris Informational 15 Schema functions for the LDAP C API October 2001 element (OUT) Address to a handle of the schema element requested. The user must not modify this memory. Return type is an ldap result code. 4.2.2 ldap_schema_get_count int ldap_schema_get_count (LDAPSchema *schema, int elementType) ldap_schema_get_count returns the count of schema elements of the type specified. Parameters are: schema A handle to the schema of a directory. elementType Type of element requested. Use the definitions listed in Section 3.1. Return value is -1 if the LDAPSchema structure is invalid or the elementType is invalid. Otherwise the return value is the count of schema elements. 4.2.3 ldap_schema_get_by_index int ldap_schema_get_by_index (LDAPSchema *schema, int index, int elementType, LDAPSchemaElement **element) ldap_schema_get_by_index is used to iterate through schema elements of a specific type. The index is zero based and goes through ldap_schema_get_count - 1. The returned handle to an LDAPSchemaElement structure, 'element', is a pointer to memory within the LDAPSchema structure, 'schema'. Therefore if 'schema' changes or is freed, 'element' may also change, or become invalid. Likewise, if the user frees or tampers with 'element', 'schema' may become corrupted. Parameters are: schema A handle to the schema of a directory. index index of the desired schema element. (Uses array numbering; starts at zero.) elementType Type of element requested. Use the definitions listed in Section 3.1. element (OUT) Address to a handle of the schema element requested. The user must not modify this memory. Return value is an ldap result code. Morris Informational 16 Schema functions for the LDAP C API October 2001 4.3 Reading fields of schema elements 4.3.1 ldap_schema_get_field_names int ldap_schema_get_field_names (LDAPSchemaElement *element, char*** fieldNames) ldap_schema_get_field_names retrieves a list of field names in a null terminated array. Parameters are: element Handle to a Schema element. fieldNames (OUT) Address of a null-terminated array of string pointers that contain all field names defined for this schema element. Free this memory with ldap_value_free [CLDAP]. Return value is an LDAP result code. 4.3.2 ldap_schema_get_field_values int ldap_schema_get_field_values (LDAPSchemaElement *element, char* fieldName, char*** values) ldap_schema_get_field_values retrieves a list of values for the field name specified. Valid field names are listed in sections 3.2 through 3.9. Some fields, although valid, may not have values (For example, LDAP_SCHEMA_OBSOLETE.) In this case values MUST be NULL and the return value MUST be LDAP_SUCCESS. If the field name does not exist values will be NULL and LDAP_NO_SUCH_ATTRIBUTE is returned. Parameters are: element Handle to a Schema element. fieldName Name of the field for which values are requested. See sections 3.2 through 3.9. values (OUT) Null-terminated array of string pointers containing the values for a field. Free this memory with ldap_value_free [CLDAP]. Return value is an LDAP result code. 4.4 Adding, modifying, and deleting. 4.4.1 ldap_schema_add Morris Informational 17 Schema functions for the LDAP C API October 2001 int ldap_schema_add (LDAP *ld, LDAPSchema *schema, int type, LDAPSchemaMod *fields[]) ldap_schema_add will construct a new schema element definition from the schema mod structures passed in and add the definition to the directory. If the LDAPSchema structure passed in is not NULL the definition will be added to it also. Parameters are: ld An LDAP session handle. schema A handle to the schema of a directory. type Type of element requested. Use the definitions listed in Section 3.1. fields An array of pointers to LDAPSchemaMod structures. Each structure represents a field in an attribute definition. ldap_schema_add ignores the 'op' field in this structure. See section 2.3. Return value is an LDAP result code. 4.4.2 ldap_schema_modify int ldap_schema_modify(LDAP *ld, LDAPSchema *schema, char* nameOrOid, int type, LDAPSchemaMod *fieldsToChange[]) ldap_schema_modify modifies an existing schema element definition. Using an existing definition in schema, this constructs a new definition according the list of fields passed in. If 'schema' is NULL, the schema is read from the directory to locate the individual definition to modify. A field with an operation code of LDAP_MOD_ADD will add values to a field, creating new fields if one does not already exist. A field with an operation code of LDAP_MOD_REPLACE will replace the existing field values, or creating new values if the field does not exist. A field with an operation of LDAP_MOD_DELETE will remove the field values listed, if they exist. Parameters are: ld An LDAP session handle. schema A handle to the schema of a directory. nameOrOid A name or OID that identifies the schema definition to modify. type Type of element to modify. Use the definitions listed in Section 3.1. Morris Informational 18 Schema functions for the LDAP C API October 2001 fields An array of pointers of LDAPSchemaMod structures. Each structure represents a field in an attribute definition. See section 2.3 Return value is an LDAP result code. 4.4.3 ldap_schema_delete int ldap_schema_delete (LDAP *ld, LDAPSchema *schema, char *nameOrOid, int type) ldap_schema_delete removes a schema element definition from the directory and from the local copy of schema in an LDAPSchema structure, 'schema'. If 'schema' is NULL, the schema is read from the directory to locate the individual definition to delete. Parameters are: ld An LDAP session handle. schema A handle to the schema of a directory. nameOrOid A name or OID that identifies the schema definition to delete. type Type of element to delete. Use the definitions listed in Section 3.1. Return value is an LDAP result code. Morris Informational 19 Schema functions for the LDAP C API October 2001 5 Sample Code #include #include #include /* * This code demonstrates the following: * - Fetching directory schema * - Reading and printing schema definitions * - Adding a schema definition. * */ void print_error_exit(int rc, char* function, LDAP *ld); int main(int argc, char *argv[]) { char *host, *dn, *pass; LDAP *ld; LDAPSchema *schema = NULL; int elementType, /* iterates through schema types */ index, /* iterates through schema elements */ field, /* iterates through fields of a element*/ value, /* iterates through values of a field */ count, /* count of schema elements */ countNames, /* count of field names */ countValues, /* count of a fields values */ rc, /* ldap return code */ port; LDAPSchemaElement *element; char** names; /* holds the field names */ char** values; /* holds the values of a field */ /* variables for adding a new attribute */ LDAPSchemaMod m_oid, m_name, m_desc, m_syntax, *mod[5]; /* syntax for a Case Ignore String */ char *syntax[] = {"1.3.6.1.4.1.1466.115.121.1.15", NULL}; char *oid [] = {"2.16.840.1.113719.1.187.4.1", NULL}; char *name[] = {"TestAttribute", NULL}; char *desc[] = {"Test attribute definition", NULL}; if (argc != 5){ printf("USAGE: sample.exe HOST PORT userDN password\n \ example: schema nldap.novell.com 389 cn=user pass"); return 1; } host = argv[1]; port = atoi( argv[2] ); Morris Informational 20 Schema functions for the LDAP C API October 2001 dn = argv[3]; pass = argv[4]; /* open an LDAP session */ if (( ld = ldap_init( host, port)) == NULL ) return 1; /* bind */ if (( rc = ldap_simple_bind_s( ld, dn, pass )) != LDAP_SUCCESS ) print_error_exit( rc, "ldap_simple_bind", ld ); /* fetch schema from the directory */ if (( rc = ldap_schema_fetch( ld, &schema )) != LDAP_SUCCESS) print_error_exit( rc, "ldap_schema_fetch", ld ); /* Iterate through all types of schema definitions */ for (elementType = LDAP_SCHEMA_ATTRIBUTE_TYPE; elementType <= LDAP_SCHEMA_DIT_STRUCTURE_RULE; elementType ++) { /* Iterate through the each definition */ count = ldap_schema_get_count(schema, elementType); for (index=0; index < count; index++) { /* Retreive the schema definition */ if (( rc = ldap_schema_get_by_index( schema, index, elementType, &element)) != LDAP_SUCCESS ) print_error_exit( rc, "ldap_schema_get_by_index", ld); /* Retreive defined field names */ ldap_schema_get_field_names( element, &names ); countNames = ldap_count_values( names ); /* Iterate through each field name*/ for (field = 0; field< countNames; field++) { printf("%s\n", names[field]); /* Retreive values of the field */ rc = ldap_schema_get_field_values( element, names[field], &values ); countValues = ldap_count_values( values ); /* Iterate through each value */ for(value = 0; value < countValues; value++) printf("\t%s\n", values[value]); ldap_value_free ( values ); } ldap_value_free( names ); } } Morris Informational 21 Schema functions for the LDAP C API October 2001 /* Build definition structure */ m_oid.fieldName = LDAP_SCHEMA_OID; m_oid.values = oid; mod[0] = &m_oid; m_name.fieldName = LDAP_SCHEMA_NAMES; m_name.values = name; mod[1] = &m_name; m_desc.fieldName = LDAP_SCHEMA_DESCRIPTION; m_desc.values = desc; mod[2] = &m_desc; m_syntax.fieldName = LDAP_SCHEMA_SYNTAX_OID; m_syntax.values = syntax; mod[3] = &m_syntax; mod[4] = NULL; /* Add new definition to the directory */ if (( rc = ldap_schema_add(ld, schema, LDAP_SCHEMA_ATTRIBUTE_TYPE, mod)) != LDAP_SUCCESS) print_error_exit( rc, "ldap_schema_add", ld ); ldap_schema_free(schema); ldap_unbind(ld); return 1; } /* print_error_exit prints the return code error (rc) from an * ldap operation and exits. */ void print_error_exit( int rc, char* function, LDAP *ld) { printf( "The following error occurred inside function %s: \ %s(%d)\n", function, ldap_err2string( rc ), rc ); ldap_unbind( ld ); exit(1); } Morris Informational 22 Schema functions for the LDAP C API October 2001 6 Security Considerations This API simplifies reading and modifiying of schema in LDAP directories. Standard LDAP is used, therfore LDAP security is not affected. 7 References [CLDAP] M. Smith, T. Howes, A. Herron, M. Wahl, A. Anantha, "The C LDAP Application Program Interface", draft-ietf-ldapext- ldap-c-api-05.txt, November 2000. [JLDAP] R. Weltman, C. Tomlinson, M. Kekic, S. Sonntag, J. Sermersheim, M. Smith, T. Howes, "The Java LDAP Application Program Interface", draft-ietf-ldapext-ldap-java-api-16.txt, May 2001 [ATTR] M. Wahl, A. Coulbeck, T. Howes, S. Kille, "Lightweight Directory Access Protocol: Attribute Syntax Definitions", RFC 2252, December 1997 8 Acknowledgments The structures and procedures explained are intended to have comparable functionality to the Java API[JLDAP]. The author thanks the Novell's eDirectory SDK team, and Standards Review Board for their review and suggestions made. 9 Author's Address Cameron Morris Novell Inc. 1800 South Novell Place Provo, UT 84606 Email: cmorris@novell.com Morris Informational 23 Schema functions for the LDAP C API September 2001 Full Copyright Statement "Copyright (C) The Internet Society (date). 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 Morris Informative - Expires April/2002 24