IBM Security Directory Server, Version 6.3.1

Event notification

Event notifications are database objects that send information about server and database events to a client. It also provides the information that is required to understand, design, and implement event notifications.

The event notification function allows a server to notify a registered client that an entry in the directory tree is changed, added, or deleted. This notification is in the form of an unsolicited message.

Registration request
To register, the client must use a bound connection. To register a client, use the supported client APIs for extended operations. An LDAP v3 extended operation request has the form:
        ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
                requestName      [0] LDAPOID,
                requestValue     [1] OCTET STRING OPTIONAL }
      
where the requestValue has the form:
requestValue ::= SEQUENCE {
                eventID         ENUMERATED {
                        LDAP_CHANGE (0)},
                baseObject      LDAPDN,
                scope           ENUMERATED {
                        baseObject              (0),
                        singleLevel             (1),
                        wholeSubtree            (2) },
                type    INTEGER OPTIONAL }
and where type has the form:
        changeType ::= ENUMERATED {
                        changeAdd               (1),
                        changeDelete            (2),
                        changeModify            (4),
                        changeModDN             (8) }
Note: If the type field is not specified, it defaults to all changes.
An LDAP v3 extended operation response has the form:
        ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
                COMPONENTS OF LDAPResult,
                responseName     [10] LDAPOID OPTIONAL,
                response         [11] OCTET STRING OPTIONAL }
Registration response
If the registration is successful, the server returns the following message and a unique registration ID:
LDAP_SUCCESS registration ID
If the registration fails, the server returns one of the following codes:
LDAP_UNWILLING_TO_PERFORM
This error code is returned if:
  • The event notification function is turned off in the server.
  • The event ID requested by the client cannot be handled by the server.
  • The client is unbound.
LDAP_NO_SUCH_OBJECT
This error code is returned if:
  • The base DN supplied by the client does not exist or is not visible to the client.
LDAP_NOT_SUPPORTED
This error code is returned if:
  • The change type that is supplied by the client cannot be handled by the server.
Usage
When an event occurs, the server sends a message to the client as an LDAP v3 unsolicited notification. The message ID is 0 and the message is in the form of an extended operation response. The responseName field is set to the registration OID. The response field contains the unique registration ID and a timestamp for when the event occurred. The time field is in Coordinated Universal Time (UTC) format.
Note: When a transaction occurs, the event notifications for the transaction steps cannot be sent until the entire transaction is completed.
Unregistering a client
Set the requestName field to the unregister request OID. In the requestValue field type the unique registration ID returned by the server from the registration request:
        requestValue ::= OCTET STRING
If the registration is successfully removed, the LDAPResult field contains LDAP_SUCCESS and the response field contains the registration ID that was removed.

If the unregistration request was unsuccessful, NO_SUCH_OBJECT is returned.

Example
#include stdio.h
#include string.h
#include ldap.h


struct berval *create_reg(int id,char *base,int scope,int type){
  struct berval *ret;
  BerElement *ber;

  if((ber = ber_alloc_t(1)) == NULL){
    printf("ber_alloc_t failed\n");
    return NULL;
  }
  if(ber_printf(ber,"{esi",id,base,scope) == (-1)){
    printf("first ber_printf failed\n");
    return NULL;
  }
  if(type != (-1)){
    if(ber_printf(ber,"i",type) == (-1)){
      printf("type ber_printf failed\n");
      return NULL;
    }
  }
  if(ber_printf(ber,"}") == (-1)){
    printf("closing ber_printf failed\n");
    return NULL;
  }

  if(ber_flatten(ber,&ret) == (-1)){
    printf("ber_flatten failed\n");
    return NULL;
  }
  ber_free(ber,1);
  return ret;
}

int main(int argc,char **argv){
  LDAP *ld;
  char *oidreq = "1.3.18.0.2.12.1";
  char *oidres;
  struct berval *valres = NULL;
  struct berval *registration;
  int rc,version, port;
  LDAPMessage *res;
  BerElement *ber;
  char *regID;

  argc--; argv++;

  port = 389;
  if(argc > 0){
    if(argc > 1) sscanf(argv[1],"%d",&port);
    ld = ldap_init(argv[0],port);
  }
  else
    ld = ldap_init("localhost",389);
  if(ld == NULL){
    printf("ldap_init failed\n");
    ldap_unbind(ld);
    return -1;
  }
  version = 3;
  ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,&version);

  if(ldap_simple_bind_s(ld,"cn=admin","secret") != LDAP_SUCCESS){
    printf("Couldn't bind\n");
    ldap_unbind(ld);
    return -1;
  }

  registration = create_reg(0,"o=sample",2,15);
  rc = ldap_extended_operation_s(ld,oidreq,registration,NULL,NULL,
                                 &oidres,&valres);
  if(rc == LDAP_SUCCESS){
    if(valres != NULL){
      if((ber = ber_init2(valres)) == NULL)
        printf("ber_init2 failed\n");
      else{
        if(ber_scanf(ber,"a",&regID) == LBER_ERROR)
          printf("ber_scanf failed\n");
        printf("registration ID: %s\n",regID);
        ber_free(ber,1);
      }
    }
    else{
      printf("valres NULL\n");
    }
  }
  else{
    printf("extended operation failed 0x%x\n",rc);
  }

  ldap_memfree(regID);
  ldap_unbind(ld);
  return 0;
}


Feedback