10Sstevel@tonic-gate
20Sstevel@tonic-gate /*
3*3857Sstevel * Portions Copyright 1998 Sun Microsystems, Inc. All rights reserved.
4*3857Sstevel * Use is subject to license terms.
5*3857Sstevel */
60Sstevel@tonic-gate
70Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
80Sstevel@tonic-gate
90Sstevel@tonic-gate /*
100Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan.
110Sstevel@tonic-gate * All rights reserved.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * abandon.c
140Sstevel@tonic-gate */
150Sstevel@tonic-gate
160Sstevel@tonic-gate #ifndef lint
170Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
180Sstevel@tonic-gate #endif
190Sstevel@tonic-gate
200Sstevel@tonic-gate #include <stdio.h>
210Sstevel@tonic-gate #include <string.h>
220Sstevel@tonic-gate
230Sstevel@tonic-gate #if !defined( MACOS ) && !defined( DOS )
240Sstevel@tonic-gate #include <sys/types.h>
250Sstevel@tonic-gate #include <sys/socket.h>
260Sstevel@tonic-gate #endif
270Sstevel@tonic-gate
280Sstevel@tonic-gate #if defined( DOS ) || defined( _WIN32 )
290Sstevel@tonic-gate #include <malloc.h>
300Sstevel@tonic-gate #include "msdos.h"
310Sstevel@tonic-gate #endif /* DOS */
320Sstevel@tonic-gate
330Sstevel@tonic-gate #ifdef MACOS
340Sstevel@tonic-gate #include <stdlib.h>
350Sstevel@tonic-gate #include "macos.h"
360Sstevel@tonic-gate #endif /* MACOS */
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include "lber.h"
390Sstevel@tonic-gate #include "ldap.h"
400Sstevel@tonic-gate #include "ldap-private.h"
410Sstevel@tonic-gate #include "ldap-int.h"
420Sstevel@tonic-gate
430Sstevel@tonic-gate #ifdef NEEDPROTOS
440Sstevel@tonic-gate static int do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls );
450Sstevel@tonic-gate #else /* NEEDPROTOS */
460Sstevel@tonic-gate static int do_abandon();
470Sstevel@tonic-gate #endif /* NEEDPROTOS */
480Sstevel@tonic-gate
ldap_build_abandon_req(LDAP * ld,int msgid,LDAPControl ** serverctrls)490Sstevel@tonic-gate BerElement * ldap_build_abandon_req( LDAP *ld, int msgid, LDAPControl ** serverctrls)
500Sstevel@tonic-gate {
510Sstevel@tonic-gate BerElement *ber;
520Sstevel@tonic-gate int rc;
530Sstevel@tonic-gate
540Sstevel@tonic-gate /* create a message to send */
550Sstevel@tonic-gate if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) {
560Sstevel@tonic-gate rc = -1;
570Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY;
580Sstevel@tonic-gate return (NULLBER);
590Sstevel@tonic-gate }
600Sstevel@tonic-gate #ifdef CLDAP
610Sstevel@tonic-gate if ( ld->ld_sb.sb_naddr > 0 ) {
620Sstevel@tonic-gate rc = ber_printf( ber, "{isti",
630Sstevel@tonic-gate ++ld->ld_msgid, ld->ld_cldapdn,
640Sstevel@tonic-gate LDAP_REQ_ABANDON, msgid );
650Sstevel@tonic-gate } else {
660Sstevel@tonic-gate #endif /* CLDAP */
670Sstevel@tonic-gate rc = ber_printf( ber, "{iti", ++ld->ld_msgid,
680Sstevel@tonic-gate LDAP_REQ_ABANDON, msgid );
690Sstevel@tonic-gate #ifdef CLDAP
700Sstevel@tonic-gate }
710Sstevel@tonic-gate #endif /* CLDAP */
720Sstevel@tonic-gate
730Sstevel@tonic-gate if ( rc == -1 ) {
740Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR;
750Sstevel@tonic-gate ber_free( ber, 1 );
760Sstevel@tonic-gate return (NULLBER);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate /* LDAPv3 */
790Sstevel@tonic-gate /* Code controls if any */
800Sstevel@tonic-gate if (serverctrls && serverctrls[0]) {
810Sstevel@tonic-gate if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){
820Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR;
830Sstevel@tonic-gate return( NULLBER );
840Sstevel@tonic-gate }
850Sstevel@tonic-gate } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) {
860Sstevel@tonic-gate /* Otherwise, is there any global server ctrls ? */
870Sstevel@tonic-gate if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){
880Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR;
890Sstevel@tonic-gate return( NULLBER );
900Sstevel@tonic-gate }
910Sstevel@tonic-gate }
920Sstevel@tonic-gate
930Sstevel@tonic-gate if ( ber_printf( ber, "}" ) == -1 ) {
940Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR;
950Sstevel@tonic-gate ber_free( ber, 1 );
960Sstevel@tonic-gate return( NULLBER );
970Sstevel@tonic-gate }
980Sstevel@tonic-gate return (ber);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate /*
1030Sstevel@tonic-gate * ldap_abandon - perform an ldap (and X.500) abandon operation. Parameters:
1040Sstevel@tonic-gate *
1050Sstevel@tonic-gate * ld LDAP descriptor
1060Sstevel@tonic-gate * msgid The message id of the operation to abandon
1070Sstevel@tonic-gate *
1080Sstevel@tonic-gate * ldap_abandon returns 0 if everything went ok, -1 otherwise.
1090Sstevel@tonic-gate *
1100Sstevel@tonic-gate * Example:
1110Sstevel@tonic-gate * ldap_abandon( ld, msgid );
1120Sstevel@tonic-gate */
1130Sstevel@tonic-gate int
ldap_abandon(LDAP * ld,int msgid)1140Sstevel@tonic-gate ldap_abandon( LDAP *ld, int msgid )
1150Sstevel@tonic-gate {
1160Sstevel@tonic-gate int rv;
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate #ifdef _REENTRANT
1190Sstevel@tonic-gate LOCK_LDAP( ld );
1200Sstevel@tonic-gate #endif
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 85, "ldap_abandon %d\n"), msgid, 0, 0 );
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate rv = do_abandon( ld, msgid, msgid , NULL);
1250Sstevel@tonic-gate #ifdef _REENTRANT
1260Sstevel@tonic-gate UNLOCK_LDAP( ld );
1270Sstevel@tonic-gate #endif
1280Sstevel@tonic-gate return (rv);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate /* ldapv3 API extensions */
1320Sstevel@tonic-gate
ldap_abandon_ext(LDAP * ld,int msgid,LDAPControl ** serverctrls,LDAPControl ** clientctrls)1330Sstevel@tonic-gate int ldap_abandon_ext(LDAP *ld, int msgid, LDAPControl **serverctrls, LDAPControl **clientctrls)
1340Sstevel@tonic-gate {
1350Sstevel@tonic-gate int rv;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate #ifdef _REENTRANT
1380Sstevel@tonic-gate LOCK_LDAP( ld );
1390Sstevel@tonic-gate #endif
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 85, "ldap_abandon %d\n"), msgid, 0, 0 );
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate rv = do_abandon( ld, msgid, msgid , NULL);
1440Sstevel@tonic-gate if (rv == -1) {
1450Sstevel@tonic-gate rv = ld->ld_errno;
1460Sstevel@tonic-gate if (rv == LDAP_SUCCESS)
1470Sstevel@tonic-gate rv = LDAP_OTHER;
1480Sstevel@tonic-gate #ifdef _REENTRANT
1490Sstevel@tonic-gate UNLOCK_LDAP( ld );
1500Sstevel@tonic-gate #endif
1510Sstevel@tonic-gate return (rv);
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate #ifdef _REENTRANT
1540Sstevel@tonic-gate UNLOCK_LDAP( ld );
1550Sstevel@tonic-gate #endif
1560Sstevel@tonic-gate return (LDAP_SUCCESS);
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate static int
do_abandon(LDAP * ld,int origid,int msgid,LDAPControl ** serverctrls)1610Sstevel@tonic-gate do_abandon( LDAP *ld, int origid, int msgid , LDAPControl **serverctrls)
1620Sstevel@tonic-gate {
1630Sstevel@tonic-gate BerElement *ber;
1640Sstevel@tonic-gate int i, err, sendabandon;
1650Sstevel@tonic-gate Sockbuf *sb;
1660Sstevel@tonic-gate #ifdef LDAP_REFERRALS
1670Sstevel@tonic-gate LDAPRequest *lr;
1680Sstevel@tonic-gate #endif /* LDAP_REFERRALS */
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate /*
1710Sstevel@tonic-gate * An abandon request looks like this:
1720Sstevel@tonic-gate * AbandonRequest ::= MessageID
1730Sstevel@tonic-gate */
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 86, "do_abandon origid %1$d, msgid %2$d\n"),
1760Sstevel@tonic-gate origid, msgid, 0 );
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate sendabandon = 1;
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate #ifdef LDAP_REFERRALS
1810Sstevel@tonic-gate /* find the request that we are abandoning */
1820Sstevel@tonic-gate for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
1830Sstevel@tonic-gate if ( lr->lr_msgid == msgid ) { /* this message */
1840Sstevel@tonic-gate break;
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate if ( lr->lr_origid == msgid ) { /* child: abandon it */
1870Sstevel@tonic-gate do_abandon( ld, msgid, lr->lr_msgid , serverctrls);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate if ( lr != NULL ) {
1920Sstevel@tonic-gate if ( origid == msgid && lr->lr_parent != NULL ) {
1930Sstevel@tonic-gate /* don't let caller abandon child requests! */
1940Sstevel@tonic-gate ld->ld_errno = LDAP_PARAM_ERROR;
1950Sstevel@tonic-gate return( -1 );
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
1980Sstevel@tonic-gate /* no need to send abandon message */
1990Sstevel@tonic-gate sendabandon = 0;
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate #endif /* LDAP_REFERRALS */
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate if ( ldap_msgdelete( ld, msgid ) == 0 ) {
2050Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS;
2060Sstevel@tonic-gate return( 0 );
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate err = 0;
2100Sstevel@tonic-gate if ( sendabandon ) {
2110Sstevel@tonic-gate if ((ber = ldap_build_abandon_req(ld, msgid, serverctrls)) == NULLBER){
2120Sstevel@tonic-gate return (-1);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate #ifdef LDAP_REFERRALS
2160Sstevel@tonic-gate if ( lr != NULL ) {
2170Sstevel@tonic-gate sb = lr->lr_conn->lconn_sb;
2180Sstevel@tonic-gate } else {
2190Sstevel@tonic-gate sb = &ld->ld_sb;
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate #else /* LDAP_REFERRALS */
2220Sstevel@tonic-gate sb = &ld->ld_sb;
2230Sstevel@tonic-gate #endif /* LDAP_REFERRALS */
2240Sstevel@tonic-gate if ( ber_flush( sb, ber, 1 ) != 0 ) {
2250Sstevel@tonic-gate ld->ld_errno = LDAP_SERVER_DOWN;
2260Sstevel@tonic-gate err = -1;
2270Sstevel@tonic-gate } else {
2280Sstevel@tonic-gate err = 0;
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate #ifdef LDAP_REFERRALS
2320Sstevel@tonic-gate if ( lr != NULL ) {
2330Sstevel@tonic-gate if ( sendabandon ) {
2340Sstevel@tonic-gate free_connection( ld, lr->lr_conn, 0, 1 );
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate if ( origid == msgid ) {
2370Sstevel@tonic-gate free_request( ld, lr );
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate #endif /* LDAP_REFERRALS */
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate if ( ld->ld_abandoned == NULL ) {
2440Sstevel@tonic-gate if ( (ld->ld_abandoned = (int *) malloc( 2 * sizeof(int) ))
2450Sstevel@tonic-gate == NULL ) {
2460Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY;
2470Sstevel@tonic-gate return( -1 );
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate i = 0;
2500Sstevel@tonic-gate } else {
2510Sstevel@tonic-gate for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
2520Sstevel@tonic-gate ; /* NULL */
2530Sstevel@tonic-gate if ( (ld->ld_abandoned = (int *) realloc( (char *)
2540Sstevel@tonic-gate ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) {
2550Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY;
2560Sstevel@tonic-gate return( -1 );
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate ld->ld_abandoned[i] = msgid;
2600Sstevel@tonic-gate ld->ld_abandoned[i + 1] = -1;
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate if ( err != -1 ) {
2630Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS;
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate return( err );
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
268