HP OpenVMS Utility Routines Manual


Previous Contents Index


LBR$SET_MOVE

The LBR$SET_MOVE routine sets the record access of LBR subroutines to move mode.

Format

LBR$SET_MOVE library_index


RETURNS


OpenVMS usage: cond_value
type: longword (unsigned)
access: write only
mechanism: by value

Longword condition value. Most utility routines return a condition value in R0. Condition values that this routine can return are listed under Condition Values Returned.


Argument

library_index


OpenVMS usage: longword_unsigned
type: longword (unsigned)
access: read only
mechanism: by reference

Library control index returned by the LBR$INI_CONTROL routine. The library_index argument is the address of the longword that contains the index.

Description

Librarian record access may be set to move mode (the default, set by LBR$SET_MOVE) or locate mode. The setting affects the operation of the LBR$GET_RECORD routine. If move mode is set, LBR$GET_RECORD copies the requested record to the specified user buffer. For details, see the description of LBR$GET_RECORD.

Condition Values Returned

LBR$_ILLCTL Specified library control index not valid.
LBR$_LIBNOTOPN Specified library not open.

LBR$UNMAP_MODULE

The LBR$UNMAP_MODULE routine unmaps a module from process P2 space.

Format

LBR$PUT_MODULE library_index, txtrfa


Arguments

library_index


OpenVMS usage: longword_unsigned
type: longword (unsigned)
access: read only
mechanism: by reference

Library control index returned by the LBR$INI_CONTROL library routine. The library_index argument is the address of the longword that contains the index.

txtrfa


OpenVMS usage: vector_longword_unsigned
type: longword (unsigned)
access: read only
mechanism: by reference

The module's record file address (RFA) of the library module header. The txtrfa argument is the address of the 2-longword array that specifies the RFA of the module header.

Description

The LBR$UNMAP_MODULE routine unmaps the module, with the record file address in txtrfa, from process P2 space. This action releases the resources used to map the module.

Unlike other LBR services that use RMS services, LBR$UNMAP_MODULE also uses system services. Because of this, the secondary status for error returns is placed in LBR$GL_SUBSTS. Use this to find further status when an error is returned.


Chapter 14
Lightweight Directory Access Protocol (LDAP) Routines

14.1 Introduction

This chapter describes the C language application programming interface (API) to the Lightweight Directory Access Protocol (LDAP). This API supports Version 3 of the LDAP API (LDAPv3), and includes support for controls, information hiding, and thread safety. The LDAP API is available on OpenVMS Alpha only.

The C LDAP API is designed to be powerful, yet simple to use. It defines compatible synchronous and asynchronous interfaces to LDAP to support a wide variety of applications. This chapter gives a brief overview of the LDAP model, and describes how the application program uses the API to obtain LDAP information. The API calls are described in detail, followed by a section that provides some example code demonstrating the use of the API.

14.1.1 Overview of the LDAP Model

LDAP is the lightweight directory access protocol, which is based on a client-server model. In this model, a client makes a TCP connection to an LDAP server, over which it sends requests and receives responses.

The LDAP information model is based on the entry, which contains information about some object (for example, a person). Entries are composed of attributes, which have a type and one or more values. Each attribute has a syntax that determines what kinds of values are allowed in the attribute (for example, ASCII characters or a jpeg photograph) and how those values behave during directory operations (for example, whether case is significant during comparisons).

Entries may be organized in a tree structure, usually based on political, geographical, or organizational boundaries. Each entry is uniquely named relative to its sibling entries by its relative distinguished name (RDN) consisting of one or more distinguished attribute values from the entry. At most, one value from each attribute may be used in the RDN. For example, the entry for the person Babs Jensen might be named with the Barbara Jensen value from the commonName attribute.

A globally unique name for an entry, called a distinguished name or DN, is constructed by concatenating the sequence of RDNs from the entry up to the root of the tree. For example, if Babs worked for the University of Michigan, the DN of her U-M entry might be the following:


cn=Barbara Jensen, o=University of Michigan, c=US 

Operations are provided to authenticate, search for and retrieve information, modify information, and add and delete entries from the tree. The next sections give an overview of how the API is used and provide detailed descriptions of the LDAP API calls that implement all of these functions.

14.1.2 Overview of LDAP API Use

An application generally uses the C LDAP API in four simple steps.

Operations can be performed either synchronously or asynchronously. The names of the synchronous functions end in _s. For example, a synchronous search can be completed by calling ldap_search_s() . An asynchronous search can be initiated by calling ldap_search() . All synchronous functions return an indication of the outcome of the operation (for example, the constant LDAP_SUCCESS or some other error code). The asynchronous functions make available to the caller the message id of the operation initiated. This id can be used in subsequent calls to ldap_result() to obtain the result(s) of the operation. An asynchronous operation can be abandoned by calling ldap_abandon() or ldap_abandon_ext() .

Results and errors are returned in an opaque structure called LDAPMessage. Functions are provided to parse this structure, step through entries and attributes returned. Functions are also provided to interpret errors. Later sections of this chapter describe these functions in more detail.

LDAPv3 servers may return referrals to other servers. By default, implementations of this API will attempt to follow referrals automatically for the application. This behavior can be disabled globally (using the ldap_set_option() call) or on a per-request basis through the use of a server control.

As in the LDAPv3 protocol, all DNs and string values that are passed into or produced by the C LDAP API are represented as UTF-8 characters. Conversion functions are described in Section 14.20.

For compatibility with existing applications, implementations of this API will, by default, use Version 2 of the LDAP protocol. Applications that intend to take advantage of LDAPv3 features will need to use the ldap_set_option() call with a LDAP_OPT_PROTOCOL_VERSION switch set to Version 3.

The file LDAP_EXAMPLE.C in SYS$EXAMPLES contains an example program that demonstrates how to use the LDAP API on OpenVMS.

14.1.3 LDAP API Use on OpenVMS Systems

This release of the LDAP API provides support for client applications written in C or C++.

In order to use the LDAP API, a program must use an include statement of the form:


#include <ldap.h> 

The LDAP.H header file includes prototypes and data structures for all of the functions that are available in the LDAP API.

The shareable image LDAP$SHR.EXE includes run-time support for LDAP applications. This shareable image resides in SYS$LIBRARY and should be included in the library IMAGELIB.OLB, which means that no special action is necessary to link or run your programs. For example:


  $ type myprog.c 
 
  /* A not very useful program */ 
  #include <stdio.h> 
  #include <ldap.h> 
  void main(int argc, char *argv[]) 
  { 
    LDAP *ld; 
    if (argc != 2) { 
      printf("usage: %s <hostname>\n",argv[0]); 
      return; 
    } 
    ld = ldap_init(argv[1],LDAP_PORT); 
    if (ld != NULL) { 
      printf("ldap_init returned 0x%p\n",ld); 
    } else { 
      printf("ldap_init failed\n"); 
    } 
  }                       
 
  $ cc myprog 
  $ link myprog 
  $ myprog :== $mydisk:[mydir]myprog.exe 
  $ myprog fred 
  ldap_init returned 0xA6748 
  $ 

14.1.4 64-bit Addressing Support

This section describes the LDAP 64-bit addressing support.

14.1.4.1 Background

OpenVMS Alpha provides support for 64-bit virtual memory addressing. Applications that are built using a suitable compiler may take advantage of the 64-bit virtual address space to map and access large amounts of data.

The OpenVMS LDAP API supports both 32- and 64-bit client applications. In order to allow this, separate entry points are provided in the library for those functions that are sensitive to pointer size.

When a user module is compiled, the header file LDAP.H determines the pointer size in effect and uses the C preprocessor to map the function names into the appropriate library entry point. This mapping is transparent to the user application and is effected by setting the /POINTER_SIZE qualifier at compilation time.

For LDAP API users, switching between different pointer sizes should need only a recompilation---no code changes are necessary.

This means that programs using the specification for the C LDAP API, as described in the Internet Engineering Task Force (IETF) documentation, can be built on OpenVMS with either 32-bit or 64-bit pointer size, without having to change the source code.

14.1.4.2 Implementation

The OpenVMS LDAP library uses 64-bit pointers internally and is capable of dealing with data structures allocated by the caller from 64-bit address space.

Applications that use 32-bit pointers will use the 32-bit function entry points in the library. This means they can pass arguments that are based on 32-bit pointers and can assume that any pointers returned by the library will be 32-bit safe.

While the mapping performed by LDAP.H is designed to be transparent, there may be occasions where it is useful (for example in debugging) to understand the consequences of having both 32- and 64-bit support in the same library.

14.1.4.2.1 Library Symbol Names

The symbols exported by the LDAP$SHR OpenVMS run-time library differ from those specified in the IETF C LDAP API specification.

The header file LDAP.H maps user references to LDAP API function names to the appropriate LDAP$SHR symbol name. Therefore, any application wishing to use the OpenVMS LDAP API must include the version of LDAP.H that ships with OpenVMS.

All of the functions in the OpenVMS LDAP library are prefixed with the facility code "LDAP$".

For those functions where the caller's pointer size is significant, the name of the 64-bit entry point will have a "_64" suffix, while the name of the 32-bit jacket will have a "_32" suffix. Functions that are not sensitive to pointer size have no special suffix.

For example, the function ldap_modify() is sensitive to the caller's pointer size (because one of its arguments is an array of pointers). Therefore, the library exports symbols for LDAP$LDAP_MODIFY_64 and LDAP$LDAP_MODIFY_32. For the function ldap_simple_bind() , which is not sensitive to the caller's pointer size, a single entry point, LDAP$LDAP_SIMPLE_BIND, exists in the library.

Because OpenVMS imposes a 31-character limit on the length of symbol names, certain functions in the library have names which are abbreviated versions of the public API name. For example, in the case of the function ldap_parse_sasl_bind_result() , the library provides two entry points, namely LDAP$LDAP_PRS_SASL_BIND_RES_32 and LDAP$LDAP_PRS_SASL_BIND_RES_64.

14.1.4.2.2 LDAP Data Structures

The LDAP API defines various data structures which are used to pass information to and from a client application. Some of these structures are opaque; that is, their internal layout is not visible to a client application. In such cases, the API may return a pointer to such a structure, but the only use of such a pointer to a client application is as a parameter to subsequent library calls.

Some structures are public. Their contents are defined by the API, and client applications may allocate and manipulate such structures or use them as parameters to LDAP functions.

All data structures used by the API are defined with "natural" alignment; that is, each member of a data structure will be aligned on an address boundary appropriate to its type.

Opaque Data Structures

The following data structures are opaque. Applications should not make any assumptions about the contents or size of such data structures.


    typedef struct ldap 
            LDAP; 
 
    typedef struct ldapmsg 
            LDAPMessage; 
 
    typedef struct berelement 
            BerElement; 

Public Data Structures

The following data structures are described in the IETF documents relating to the LDAP API, and definitions are provided for them in LDAP.H. Applications may allocate and manipulate such structures, as well as use them in calls to the LDAP API.


    typedef struct berval { .. } 
            BerValue; 
 
    typedef struct ldapapiinfo { .. } 
            LDAPAPIInfo; 
 
    typedef struct ldap_apifeature_info { .. } 
            LDAPAPIFeatureInfo; 
 
    typedef struct ldapcontrol { .. } 
            LDAPControl; 
 
    typedef struct ldapmod { .. } 
            LDAPMod; 

Note that the pointer size in effect at compilation time determines the layout of data structures, which themselves contain pointer fields. Since all of the public data structures listed here contain one or more pointers, their size and layout will differ depending on the pointer size.

For example, in the case of the structure berval, the API provides the following definition:


 struct berval { 
      ber_len_t      bv_len; 
      char           *bv_val; 
 } BerValue; 

(where ber_len_t is equivalent on OpenVMS to an unsigned 32-bit integer). For a module compiled using 32-bit pointer size, the layout of a BerValue at address A would look like this:


In the case of a 64-bit compilation, the layout would be:


The following code would therefore work correctly regardless of pointer size:


     #include <ldap.h> 
     . 
     . 
     . 
       char       *buff; 
       BerValue   val; 
     . 
     . 
     . 
       buff = (char *)malloc(255); 
     . 
     . 
     . 
       val.bv_len = 255; 
       val.bv_val = buff; 
     . 
     . 
     . 
 

14.1.4.3 Mixing Pointer Sizes

Two modules that include LDAP.H can be compiled with different pointer sizes and linked together. While each module may use the LDAP API on its own, it may not be possible for both modules to share LDAP-related data.

None of the public LDAP data structures is directly compatible between 32- and 64-bit modules. For example, a BerValue that has been allocated by a 32-bit module does not have the same layout as a BerValue which a 64-bit module expects to see, and consequently cannot be exchanged between two such modules without some sort of data conversion taking place.

Opaque data structures (such as LDAP *) have only a single structure definition inside the library, and so pointers to such structures may be exchanged between 32- and 64-bit callers. Note that these structures are allocated only by the library itself, and, in the case of a 64-bit caller, these structures may be allocated in 64-bit space. So while the LDAP handle returned to a 32-bit caller of ldap_init() could safely be used by a 64-bit module, the reverse may not be true.

14.1.5 Multithreading Support

The OpenVMS LDAP API may be used by a multi-threaded application. Two of the functions in the library, ldap_perror() and ldap_result2error() , are not thread-safe.

14.2 Common Data Structures and Memory Handling

The following are definitions of some data structures that are common to several LDAP API functions.


        
typedef struct ldap LDAP; 
        
typedef struct berelement BerElement; 
        
typedef struct ldapmsg LDAPMessage; 
        
typedef struct berval { 
    ber_len_t       bv_len;                
    char            *bv_val;        
} BerValue; 
 
        
struct timeval; 
 

The LDAP structure is an opaque data type that represents an LDAP session. Typically, this corresponds to a connection to a single server, but it may encompass several server connections in LDAPv3 referrals.

The LDAPMessage structure is an opaque data type that is used to return entry, reference, result, and error information. An LDAPMessage structure may represent the beginning of a list or a chain of messages that contain a series of entries, references, and result messages that are returned by LDAP operations, such as search. LDAP API functions, such as ldap_parse_result() , that operate on message chains which may contain more than one result message, always operate on the first result message in the chain. See Section 14.17 for more information.

The BerElement structure is an opaque data type that is used to hold data and state information about encoded data.

The berval structure is used to represent arbitrary binary data, and its fields have the following meanings:
bv_len Length of data in bytes.
bv_val A pointer to the data itself.

The timeval structure is used to represent an interval of time, and its fields have the following meanings:
tv_sec Seconds component of time interval.
tv_usec Microseconds component of time interval.

All memory that is allocated by a function in this C LDAP API and returned to the caller should be disposed of by calling the appropriate free function provided by this API. The correct free function to call is documented in each section of this chapter where a function that allocates memory is described.

Memory that is allocated outside of the C LDAP API must not be disposed of using a function provided by this API.

The following is a complete list of free functions that are used to dispose of allocated memory:


   ber_bvecfree() 
 
   ber_bvfree() 
 
   ber_free() 
 
   ldap_control_free() 
 
   ldap_controls_free() 
 
   ldap_memfree() 
 
   ldap_msgfree() 
 
   ldap_value_free() 
 
   ldap_value_free_len() 
 

14.3 LDAP Error Codes

Many of the LDAP API functions return LDAP error codes, some of which indicate local errors and some of which may be returned by servers. All of the LDAP error codes returned will be positive integers; those between 0x00 and 0x50 are returned from the LDAP server, those above 0x50 are generated by the API itself. Supported error codes are as follows (hexadecimal values are given in parentheses after the constant):


     LDAP_SUCCESS (0x00) 
     
     LDAP_OPERATIONS_ERROR (0x01) 
 
     LDAP_PROTOCOL_ERROR (0x02) 
 
     LDAP_TIMELIMIT_EXCEEDED (0x03) 
 
     LDAP_SIZELIMIT_EXCEEDED (0x04) 
 
     LDAP_COMPARE_FALSE (0x05) 
 
     LDAP_COMPARE_TRUE (0x06) 
 
     LDAP_STRONG_AUTH_NOT_SUPPORTED (0x07) 
 
     LDAP_STRONG_AUTH_REQUIRED (0x08) 
 
     LDAP_REFERRAL (0x0a)                        -- new in LDAPv3 
 
     LDAP_ADMINLIMIT_EXCEEDED (0x0b)             -- new in LDAPv3 
 
     LDAP_UNAVAILABLE_CRITICAL_EXTENSION (0x0c)  -- new in LDAPv3 
 
     LDAP_CONFIDENTIALITY_REQUIRED (0x0d)        -- new in LDAPv3 
 
     LDAP_SASL_BIND_IN_PROGRESS (0x0e)           -- new in LDAPv3 
 
     LDAP_NO_SUCH_ATTRIBUTE (0x10) 
 
     LDAP_UNDEFINED_TYPE (0x11) 
 
     LDAP_INAPPROPRIATE_MATCHING (0x12) 
 
     LDAP_CONSTRAINT_VIOLATION (0x13) 
 
     LDAP_TYPE_OR_VALUE_EXISTS (0x14) 
 
     LDAP_INVALID_SYNTAX (0x15) 
 
     LDAP_NO_SUCH_OBJECT (0x20) 
 
     LDAP_ALIAS_PROBLEM (0x21) 
 
     LDAP_INVALID_DN_SYNTAX (0x22) 
 
     LDAP_IS_LEAF (0x23)                    -- not used in LDAPv3 
 
     LDAP_ALIAS_DEREF_PROBLEM (0x24) 
 
     LDAP_INAPPROPRIATE_AUTH (0x30) 
 
     LDAP_INVALID_CREDENTIALS (0x31) 
 
     LDAP_INSUFFICIENT_ACCESS (0x32) 
 
     LDAP_BUSY (0x33) 
 
     LDAP_UNAVAILABLE (0x34) 
 
     LDAP_UNWILLING_TO_PERFORM (0x35) 
 
     LDAP_LOOP_DETECT (0x36) 
 
     LDAP_NAMING_VIOLATION (0x40) 
 
     LDAP_OBJECT_CLASS_VIOLATION (0x41) 
 
     LDAP_NOT_ALLOWED_ON_NONLEAF (0x42) 
 
     LDAP_NOT_ALLOWED_ON_RDN (0x43) 
 
     LDAP_ALREADY_EXISTS (0x44) 
 
     LDAP_NO_OBJECT_CLASS_MODS (0x45) 
 
     LDAP_RESULTS_TOO_LARGE (0x46)            -- reserved for CLDA 
 
     LDAP_AFFECTS_MULTIPLE_DSAS (0x47)        -- new in LDAPv3 
 
     LDAP_OTHER (0x50) 
 
     LDAP_SERVER_DOWN (0x51) 
 
     LDAP_LOCAL_ERROR (0x52) 
 
     LDAP_ENCODING_ERROR (0x53) 
 
     LDAP_DECODING_ERROR (0x54) 
 
     LDAP_TIMEOUT (0x55) 
 
     LDAP_AUTH_UNKNOWN (0x56) 
 
     LDAP_FILTER_ERROR (0x57) 
  
     LDAP_USER_CANCELLED (0x58) 
 
     LDAP_PARAM_ERROR (0x59) 
 
     LDAP_NO_MEMORY (0x5a) 
 
     LDAP_CONNECT_ERROR (0x5b) 
 
     LDAP_NOT_SUPPORTED (0x5c) 
 
     LDAP_CONTROL_NOT_FOUND (0x5d) 
 
     LDAP_NO_RESULTS_RETURNED (0x5e) 
 
     LDAP_MORE_RESULTS_TO_RETURN (0x5f) 
 
     LDAP_CLIENT_LOOP (0x60) 
 
     LDAP_REFERRAL_LIMIT_EXCEEDED (0x61) 
 


Previous Next Contents Index