1*0Sstevel@tonic-gate 2*0Sstevel@tonic-gate /* 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * Portions Copyright %G% Sun Microsystems, Inc. All Rights Reserved 5*0Sstevel@tonic-gate * 6*0Sstevel@tonic-gate */ 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate /* 11*0Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan. 12*0Sstevel@tonic-gate * All rights reserved. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * abandon.c 15*0Sstevel@tonic-gate */ 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate #ifndef lint 18*0Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; 19*0Sstevel@tonic-gate #endif 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gate #include <stdio.h> 22*0Sstevel@tonic-gate #include <string.h> 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate #if !defined( MACOS ) && !defined( DOS ) 25*0Sstevel@tonic-gate #include <sys/types.h> 26*0Sstevel@tonic-gate #include <sys/socket.h> 27*0Sstevel@tonic-gate #endif 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #if defined( DOS ) || defined( _WIN32 ) 30*0Sstevel@tonic-gate #include <malloc.h> 31*0Sstevel@tonic-gate #include "msdos.h" 32*0Sstevel@tonic-gate #endif /* DOS */ 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate #ifdef MACOS 35*0Sstevel@tonic-gate #include <stdlib.h> 36*0Sstevel@tonic-gate #include "macos.h" 37*0Sstevel@tonic-gate #endif /* MACOS */ 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate #include "lber.h" 40*0Sstevel@tonic-gate #include "ldap.h" 41*0Sstevel@tonic-gate #include "ldap-private.h" 42*0Sstevel@tonic-gate #include "ldap-int.h" 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate #ifdef NEEDPROTOS 45*0Sstevel@tonic-gate static int do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls ); 46*0Sstevel@tonic-gate #else /* NEEDPROTOS */ 47*0Sstevel@tonic-gate static int do_abandon(); 48*0Sstevel@tonic-gate #endif /* NEEDPROTOS */ 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate BerElement * ldap_build_abandon_req( LDAP *ld, int msgid, LDAPControl ** serverctrls) 51*0Sstevel@tonic-gate { 52*0Sstevel@tonic-gate BerElement *ber; 53*0Sstevel@tonic-gate int rc; 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate /* create a message to send */ 56*0Sstevel@tonic-gate if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { 57*0Sstevel@tonic-gate rc = -1; 58*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 59*0Sstevel@tonic-gate return (NULLBER); 60*0Sstevel@tonic-gate } 61*0Sstevel@tonic-gate #ifdef CLDAP 62*0Sstevel@tonic-gate if ( ld->ld_sb.sb_naddr > 0 ) { 63*0Sstevel@tonic-gate rc = ber_printf( ber, "{isti", 64*0Sstevel@tonic-gate ++ld->ld_msgid, ld->ld_cldapdn, 65*0Sstevel@tonic-gate LDAP_REQ_ABANDON, msgid ); 66*0Sstevel@tonic-gate } else { 67*0Sstevel@tonic-gate #endif /* CLDAP */ 68*0Sstevel@tonic-gate rc = ber_printf( ber, "{iti", ++ld->ld_msgid, 69*0Sstevel@tonic-gate LDAP_REQ_ABANDON, msgid ); 70*0Sstevel@tonic-gate #ifdef CLDAP 71*0Sstevel@tonic-gate } 72*0Sstevel@tonic-gate #endif /* CLDAP */ 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate if ( rc == -1 ) { 75*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 76*0Sstevel@tonic-gate ber_free( ber, 1 ); 77*0Sstevel@tonic-gate return (NULLBER); 78*0Sstevel@tonic-gate } 79*0Sstevel@tonic-gate /* LDAPv3 */ 80*0Sstevel@tonic-gate /* Code controls if any */ 81*0Sstevel@tonic-gate if (serverctrls && serverctrls[0]) { 82*0Sstevel@tonic-gate if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){ 83*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 84*0Sstevel@tonic-gate return( NULLBER ); 85*0Sstevel@tonic-gate } 86*0Sstevel@tonic-gate } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) { 87*0Sstevel@tonic-gate /* Otherwise, is there any global server ctrls ? */ 88*0Sstevel@tonic-gate if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){ 89*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 90*0Sstevel@tonic-gate return( NULLBER ); 91*0Sstevel@tonic-gate } 92*0Sstevel@tonic-gate } 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate if ( ber_printf( ber, "}" ) == -1 ) { 95*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 96*0Sstevel@tonic-gate ber_free( ber, 1 ); 97*0Sstevel@tonic-gate return( NULLBER ); 98*0Sstevel@tonic-gate } 99*0Sstevel@tonic-gate return (ber); 100*0Sstevel@tonic-gate } 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate /* 104*0Sstevel@tonic-gate * ldap_abandon - perform an ldap (and X.500) abandon operation. Parameters: 105*0Sstevel@tonic-gate * 106*0Sstevel@tonic-gate * ld LDAP descriptor 107*0Sstevel@tonic-gate * msgid The message id of the operation to abandon 108*0Sstevel@tonic-gate * 109*0Sstevel@tonic-gate * ldap_abandon returns 0 if everything went ok, -1 otherwise. 110*0Sstevel@tonic-gate * 111*0Sstevel@tonic-gate * Example: 112*0Sstevel@tonic-gate * ldap_abandon( ld, msgid ); 113*0Sstevel@tonic-gate */ 114*0Sstevel@tonic-gate int 115*0Sstevel@tonic-gate ldap_abandon( LDAP *ld, int msgid ) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate int rv; 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate #ifdef _REENTRANT 120*0Sstevel@tonic-gate LOCK_LDAP( ld ); 121*0Sstevel@tonic-gate #endif 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 85, "ldap_abandon %d\n"), msgid, 0, 0 ); 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate rv = do_abandon( ld, msgid, msgid , NULL); 126*0Sstevel@tonic-gate #ifdef _REENTRANT 127*0Sstevel@tonic-gate UNLOCK_LDAP( ld ); 128*0Sstevel@tonic-gate #endif 129*0Sstevel@tonic-gate return (rv); 130*0Sstevel@tonic-gate } 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate /* ldapv3 API extensions */ 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate int ldap_abandon_ext(LDAP *ld, int msgid, LDAPControl **serverctrls, LDAPControl **clientctrls) 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate int rv; 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate #ifdef _REENTRANT 139*0Sstevel@tonic-gate LOCK_LDAP( ld ); 140*0Sstevel@tonic-gate #endif 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 85, "ldap_abandon %d\n"), msgid, 0, 0 ); 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate rv = do_abandon( ld, msgid, msgid , NULL); 145*0Sstevel@tonic-gate if (rv == -1) { 146*0Sstevel@tonic-gate rv = ld->ld_errno; 147*0Sstevel@tonic-gate if (rv == LDAP_SUCCESS) 148*0Sstevel@tonic-gate rv = LDAP_OTHER; 149*0Sstevel@tonic-gate #ifdef _REENTRANT 150*0Sstevel@tonic-gate UNLOCK_LDAP( ld ); 151*0Sstevel@tonic-gate #endif 152*0Sstevel@tonic-gate return (rv); 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate #ifdef _REENTRANT 155*0Sstevel@tonic-gate UNLOCK_LDAP( ld ); 156*0Sstevel@tonic-gate #endif 157*0Sstevel@tonic-gate return (LDAP_SUCCESS); 158*0Sstevel@tonic-gate } 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate static int 162*0Sstevel@tonic-gate do_abandon( LDAP *ld, int origid, int msgid , LDAPControl **serverctrls) 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate BerElement *ber; 165*0Sstevel@tonic-gate int i, err, sendabandon; 166*0Sstevel@tonic-gate Sockbuf *sb; 167*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 168*0Sstevel@tonic-gate LDAPRequest *lr; 169*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate /* 172*0Sstevel@tonic-gate * An abandon request looks like this: 173*0Sstevel@tonic-gate * AbandonRequest ::= MessageID 174*0Sstevel@tonic-gate */ 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 86, "do_abandon origid %1$d, msgid %2$d\n"), 177*0Sstevel@tonic-gate origid, msgid, 0 ); 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate sendabandon = 1; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 182*0Sstevel@tonic-gate /* find the request that we are abandoning */ 183*0Sstevel@tonic-gate for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { 184*0Sstevel@tonic-gate if ( lr->lr_msgid == msgid ) { /* this message */ 185*0Sstevel@tonic-gate break; 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate if ( lr->lr_origid == msgid ) { /* child: abandon it */ 188*0Sstevel@tonic-gate do_abandon( ld, msgid, lr->lr_msgid , serverctrls); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate if ( lr != NULL ) { 193*0Sstevel@tonic-gate if ( origid == msgid && lr->lr_parent != NULL ) { 194*0Sstevel@tonic-gate /* don't let caller abandon child requests! */ 195*0Sstevel@tonic-gate ld->ld_errno = LDAP_PARAM_ERROR; 196*0Sstevel@tonic-gate return( -1 ); 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate if ( lr->lr_status != LDAP_REQST_INPROGRESS ) { 199*0Sstevel@tonic-gate /* no need to send abandon message */ 200*0Sstevel@tonic-gate sendabandon = 0; 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate if ( ldap_msgdelete( ld, msgid ) == 0 ) { 206*0Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS; 207*0Sstevel@tonic-gate return( 0 ); 208*0Sstevel@tonic-gate } 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate err = 0; 211*0Sstevel@tonic-gate if ( sendabandon ) { 212*0Sstevel@tonic-gate if ((ber = ldap_build_abandon_req(ld, msgid, serverctrls)) == NULLBER){ 213*0Sstevel@tonic-gate return (-1); 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 217*0Sstevel@tonic-gate if ( lr != NULL ) { 218*0Sstevel@tonic-gate sb = lr->lr_conn->lconn_sb; 219*0Sstevel@tonic-gate } else { 220*0Sstevel@tonic-gate sb = &ld->ld_sb; 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate #else /* LDAP_REFERRALS */ 223*0Sstevel@tonic-gate sb = &ld->ld_sb; 224*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 225*0Sstevel@tonic-gate if ( ber_flush( sb, ber, 1 ) != 0 ) { 226*0Sstevel@tonic-gate ld->ld_errno = LDAP_SERVER_DOWN; 227*0Sstevel@tonic-gate err = -1; 228*0Sstevel@tonic-gate } else { 229*0Sstevel@tonic-gate err = 0; 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate } 232*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS 233*0Sstevel@tonic-gate if ( lr != NULL ) { 234*0Sstevel@tonic-gate if ( sendabandon ) { 235*0Sstevel@tonic-gate free_connection( ld, lr->lr_conn, 0, 1 ); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate if ( origid == msgid ) { 238*0Sstevel@tonic-gate free_request( ld, lr ); 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate } 241*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */ 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate if ( ld->ld_abandoned == NULL ) { 245*0Sstevel@tonic-gate if ( (ld->ld_abandoned = (int *) malloc( 2 * sizeof(int) )) 246*0Sstevel@tonic-gate == NULL ) { 247*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 248*0Sstevel@tonic-gate return( -1 ); 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate i = 0; 251*0Sstevel@tonic-gate } else { 252*0Sstevel@tonic-gate for ( i = 0; ld->ld_abandoned[i] != -1; i++ ) 253*0Sstevel@tonic-gate ; /* NULL */ 254*0Sstevel@tonic-gate if ( (ld->ld_abandoned = (int *) realloc( (char *) 255*0Sstevel@tonic-gate ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) { 256*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 257*0Sstevel@tonic-gate return( -1 ); 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate ld->ld_abandoned[i] = msgid; 261*0Sstevel@tonic-gate ld->ld_abandoned[i + 1] = -1; 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate if ( err != -1 ) { 264*0Sstevel@tonic-gate ld->ld_errno = LDAP_SUCCESS; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate return( err ); 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate 269