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:
where the requestValue has the form:ExtendedRequest ::= [APPLICATION 23] SEQUENCE { requestName [0] LDAPOID, requestValue [1] OCTET STRING OPTIONAL }
and where type has the form:requestValue ::= SEQUENCE { eventID ENUMERATED { LDAP_CHANGE (0)}, baseObject LDAPDN, scope ENUMERATED { baseObject (0), singleLevel (1), wholeSubtree (2) }, type INTEGER OPTIONAL }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:
If the registration fails, the server returns one of the following codes:LDAP_SUCCESS registration ID
This error code is returned if:LDAP_UNWILLING_TO_PERFORM- 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.
This error code is returned if:LDAP_NO_SUCH_OBJECT- The base DN supplied by the client does not exist or is not visible to the client.
This error code is returned if:LDAP_NOT_SUPPORTED- 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:
If the registration is successfully removed, the LDAPResult field contains LDAP_SUCCESS and the response field contains the registration ID that was removed.requestValue ::= OCTET STRINGIf 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",®ID) == 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; }