/* * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* Portions * Copyright (c) 1990 Regents of the University of Michigan. * All rights reserved. * * abandon.c */ #include "portable.h" #include #include #include #include #include #include "ldap-int.h" static int do_abandon LDAP_P(( LDAP *ld, int origid, int msgid, LDAPControl **sctrls, LDAPControl **cctrls)); /* * ldap_abandon_ext - perform an ldap extended abandon operation. * * Parameters: * ld LDAP descriptor * msgid The message id of the operation to abandon * scntrls Server Controls * ccntrls Client Controls * * ldap_abandon_ext returns a LDAP error code. * (LDAP_SUCCESS if everything went ok) * * Example: * ldap_abandon_ext( ld, msgid, scntrls, ccntrls ); */ int ldap_abandon_ext( LDAP *ld, int msgid, LDAPControl **sctrls, LDAPControl **cctrls ) { Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 ); return do_abandon( ld, msgid, msgid, sctrls, cctrls ); } /* * ldap_abandon - perform an ldap abandon operation. Parameters: * * ld LDAP descriptor * msgid The message id of the operation to abandon * * ldap_abandon returns 0 if everything went ok, -1 otherwise. * * Example: * ldap_abandon( ld, msgid ); */ int ldap_abandon( LDAP *ld, int msgid ) { Debug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 ); return do_abandon( ld, msgid, msgid, NULL, NULL ) == LDAP_SUCCESS ? 0 : -1; } static int do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **sctrls, LDAPControl **cctrls) { BerElement *ber; int i, err, sendabandon; Sockbuf *sb; #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS LDAPRequest *lr; #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ /* * An abandon request looks like this: * AbandonRequest ::= MessageID */ Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n", origid, msgid, 0 ); sendabandon = 1; #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS /* find the request that we are abandoning */ for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { if ( lr->lr_msgid == msgid ) { /* this message */ break; } if ( lr->lr_origid == msgid ) {/* child: abandon it */ (void) do_abandon( ld, msgid, lr->lr_msgid, sctrls, cctrls ); } } if ( lr != NULL ) { if ( origid == msgid && lr->lr_parent != NULL ) { /* don't let caller abandon child requests! */ ld->ld_errno = LDAP_PARAM_ERROR; return( LDAP_PARAM_ERROR ); } if ( lr->lr_status != LDAP_REQST_INPROGRESS ) { /* no need to send abandon message */ sendabandon = 0; } } #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ if ( ldap_msgdelete( ld, msgid ) == 0 ) { ld->ld_errno = LDAP_SUCCESS; return LDAP_SUCCESS; } err = 0; if ( sendabandon ) { /* create a message to send */ if ( (ber = ldap_alloc_ber_with_options( ld )) == NULLBER ) { err = -1; ld->ld_errno = LDAP_NO_MEMORY; } else { #ifdef LDAP_CONNECTIONLESS if ( ld->ld_cldapnaddr > 0 ) { err = ber_printf( ber, "{isti", /* leave open '}' */ ++ld->ld_msgid, ld->ld_cldapdn, LDAP_REQ_ABANDON, msgid ); } else #endif /* LDAP_CONNECTIONLESS */ { err = ber_printf( ber, "{iti", /* leave open '}' */ ++ld->ld_msgid, LDAP_REQ_ABANDON, msgid ); } if( err == -1 ) { /* encoding error */ ld->ld_errno = LDAP_ENCODING_ERROR; } else { /* Put Server Controls */ if ( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) { err = -1; } else { /* close '{' */ err = ber_printf( ber, "}" ); if( err == -1 ) { /* encoding error */ ld->ld_errno = LDAP_ENCODING_ERROR; } } } if ( err == -1 ) { ber_free( ber, 1 ); } else { /* send the message */ #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS if ( lr != NULL ) { sb = lr->lr_conn->lconn_sb; } else #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ { sb = &ld->ld_sb; } if ( ber_flush( sb, ber, 1 ) != 0 ) { ld->ld_errno = LDAP_SERVER_DOWN; err = -1; } else { err = 0; } } } } #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS if ( lr != NULL ) { if ( sendabandon ) { ldap_free_connection( ld, lr->lr_conn, 0, 1 ); } if ( origid == msgid ) { ldap_free_request( ld, lr ); } } #endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ if ( ld->ld_abandoned == NULL ) { if ( (ld->ld_abandoned = (int *) malloc( 2 * sizeof(int) )) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( ld->ld_errno ); } i = 0; } else { for ( i = 0; ld->ld_abandoned[i] != -1; i++ ) ; /* NULL */ if ( (ld->ld_abandoned = (int *) realloc( (char *) ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( ld->ld_errno ); } } ld->ld_abandoned[i] = msgid; ld->ld_abandoned[i + 1] = -1; if ( err != -1 ) { ld->ld_errno = LDAP_SUCCESS; } return( ld->ld_errno ); }