xref: /onnv-gate/usr/src/lib/libldap4/common/abandon.c (revision 3857:21b9b714e4ab)
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