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 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 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 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 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