Пример #1
0
/*
 * 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 )
{
	int	rc;

	Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );

	/* check client controls */
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif

	rc = ldap_int_client_controls( ld, cctrls );
	if ( rc == LDAP_SUCCESS ) {
		rc = do_abandon( ld, msgid, msgid, sctrls, 1 );
	}

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif

	return rc;
}
Пример #2
0
int
ldap_pvt_discard(
    LDAP *ld,
    ber_int_t msgid )
{
    int	rc;

    LDAP_MUTEX_LOCK( &ld->ld_req_mutex );
    rc = do_abandon( ld, msgid, msgid, NULL, 0 );
    LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );
    return rc;
}
Пример #3
0
int
ldap_pvt_discard(
	LDAP *ld,
	ber_int_t msgid )
{
	int	rc;

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif

	rc = do_abandon( ld, msgid, msgid, NULL, 0 );

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif

	return rc;
}
Пример #4
0
int main(object me, string arg)
{
    mapping skills;

	if( !arg || arg=="" ) return notify_fail("你要放弃哪一项技能?\n");

	skills=me->query_skills();
	if( !skills || undefinedp(skills[arg]) )
	    return notify_fail("你并没有学过这项技能。\n");

	if((int)skills[arg]>=10) {
	    write("你确定要放弃"+to_chinese(arg)+
		    "?(y/n)");
	    input_to("do_abandon",me,arg);
	} else
	    do_abandon("yes",me,arg);
	
	return 1;
}
Пример #5
0
/*
 * 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 )
{
	int rc;
#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ARGS, "ldap_abandon_ext %d\n", msgid, 0, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
#endif

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	return do_abandon( ld, msgid, msgid, sctrls, cctrls );
}
Пример #6
0
/*
 * 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 )
{
    int	rc;

    Debug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );

    /* check client controls */
    LDAP_MUTEX_LOCK( &ld->ld_req_mutex );

    rc = ldap_int_client_controls( ld, cctrls );
    if ( rc == LDAP_SUCCESS ) {
        rc = do_abandon( ld, msgid, msgid, sctrls, 1 );
    }

    LDAP_MUTEX_UNLOCK( &ld->ld_req_mutex );

    return rc;
}
Пример #7
0
/*
 * LDAPv3 extended abandon.
 * Returns an LDAP error code.
 */
int LDAP_CALL ldap_abandon_ext(LDAP *ld, int msgid, LDAPControl **serverctrls,
                               LDAPControl **clientctrls) {
  int rc;

  LDAPDebug(LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0);

  if (!NSLDAPI_VALID_LDAP_POINTER(ld)) {
    return (LDAP_PARAM_ERROR);
  }

  LDAP_MUTEX_LOCK(ld, LDAP_CONN_LOCK);
  LDAP_MUTEX_LOCK(ld, LDAP_REQ_LOCK);
  rc = do_abandon(ld, msgid, msgid, serverctrls, clientctrls);

  /*
   * XXXmcs should use cache function pointers to hook in memcache
   */
  ldap_memcache_abandon(ld, msgid);

  LDAP_MUTEX_UNLOCK(ld, LDAP_REQ_LOCK);
  LDAP_MUTEX_UNLOCK(ld, LDAP_CONN_LOCK);

  return (rc);
}
Пример #8
0
static int
do_abandon(
	LDAP *ld,
	ber_int_t origid,
	ber_int_t msgid,
	LDAPControl **sctrls,
	int sendabandon )
{
	BerElement	*ber;
	int		i, err;
	Sockbuf		*sb;
	LDAPRequest	*lr;

	Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
		origid, msgid, 0 );

	/* find the request that we are abandoning */
start_again:;
	lr = ld->ld_requests;
	while ( lr != NULL ) {
		/* this message */
		if ( lr->lr_msgid == msgid ) {
			break;
		}

		/* child: abandon it */
		if ( lr->lr_origid == msgid && !lr->lr_abandoned ) {
			(void)do_abandon( ld, lr->lr_origid, lr->lr_msgid,
				sctrls, sendabandon );

			/* restart, as lr may now be dangling... */
			goto start_again;
		}

		lr = lr->lr_next;
	}

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

	/* ldap_msgdelete locks the res_mutex. Give up the req_mutex
	 * while we're in there.
	 */
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
	err = ldap_msgdelete( ld, msgid );
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	if ( err == 0 ) {
		ld->ld_errno = LDAP_SUCCESS;
		return LDAP_SUCCESS;
	}

	/* fetch again the request that we are abandoning */
	if ( lr != NULL ) {
		for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
			/* this message */
			if ( lr->lr_msgid == msgid ) {
				break;
			}
		}
	}

	err = 0;
	if ( sendabandon ) {
		if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
			/* not connected */
			err = -1;
			ld->ld_errno = LDAP_SERVER_DOWN;

		} else if ( ( ber = ldap_alloc_ber_with_options( ld ) ) == NULL ) {
			/* BER element allocation failed */
			err = -1;
			ld->ld_errno = LDAP_NO_MEMORY;

		} else {
			/*
			 * We already have the mutex in LDAP_R_COMPILE, so
			 * don't try to get it again.
			 *		LDAP_NEXT_MSGID(ld, i);
			 */

			i = ++(ld)->ld_msgid;
#ifdef LDAP_CONNECTIONLESS
			if ( LDAP_IS_UDP(ld) ) {
				struct sockaddr sa = {0};
				/* dummy, filled with ldo_peer in request.c */
				err = ber_write( ber, &sa, sizeof(sa), 0 );
			}
			if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version ==
				LDAP_VERSION2 )
			{
				char *dn = ld->ld_options.ldo_cldapdn;
				if (!dn) dn = "";
				err = ber_printf( ber, "{isti",  /* '}' */
					i, dn,
					LDAP_REQ_ABANDON, msgid );
			} else
#endif
			{
				/* create a message to send */
				err = ber_printf( ber, "{iti",  /* '}' */
					i,
					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, /*{*/ "N}" );

					if ( err == -1 ) {
						/* encoding error */
						ld->ld_errno = LDAP_ENCODING_ERROR;
					}
				}
			}

			if ( err == -1 ) {
				ber_free( ber, 1 );

			} else {
				/* send the message */
				if ( lr != NULL ) {
					assert( lr->lr_conn != NULL );
					sb = lr->lr_conn->lconn_sb;
				} else {
					sb = ld->ld_sb;
				}

				if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) != 0 ) {
					ld->ld_errno = LDAP_SERVER_DOWN;
					err = -1;
				} else {
					err = 0;
				}
			}
		}
	}

	if ( lr != NULL ) {
		if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
			ldap_free_connection( ld, lr->lr_conn, 0, 1 );
		}

		if ( origid == msgid ) {
			ldap_free_request( ld, lr );

		} else {
			lr->lr_abandoned = 1;
		}
	}

#ifdef LDAP_R_COMPILE
	/* ld_abandoned is actually protected by the ld_res_mutex;
	 * give up the ld_req_mutex and get the other */
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
#endif

	/* use bisection */
	i = 0;
	if ( ld->ld_nabandoned == 0 ||
		ldap_int_bisect_find( ld->ld_abandoned, ld->ld_nabandoned, msgid, &i ) == 0 )
	{
		ldap_int_bisect_insert( &ld->ld_abandoned, &ld->ld_nabandoned, msgid, i );
	}

	if ( err != -1 ) {
		ld->ld_errno = LDAP_SUCCESS;
	}

#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	return( ld->ld_errno );
}
Пример #9
0
static int
do_abandon(
	LDAP *ld,
	ber_int_t origid,
	ber_int_t msgid,
	LDAPControl **sctrls,
	LDAPControl **cctrls)
{
	BerElement	*ber;
	int		i, err, sendabandon;
	ber_int_t *old_abandon;
	Sockbuf		*sb;
	LDAPRequest	*lr;

#ifdef NEW_LOGGING
	LDAP_LOG ( OPERATION, ARGS, "do_abandon %d, msgid %d\n", origid, msgid, 0 );
#else
	Debug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
		origid, msgid, 0 );
#endif

	sendabandon = 1;

	/* 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;
		}
	}

	if ( ldap_msgdelete( ld, msgid ) == 0 ) {
		ld->ld_errno = LDAP_SUCCESS;
		return LDAP_SUCCESS;
	}

	err = 0;
	if ( sendabandon ) {
		if( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
			/* not connected */
			err = -1;
			ld->ld_errno = LDAP_SERVER_DOWN;

		} else if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
			/* BER element alocation failed */
			err = -1;
			ld->ld_errno = LDAP_NO_MEMORY;

		} else {
#ifdef LDAP_CONNECTIONLESS
			if ( LDAP_IS_UDP(ld) ) {
			    err = ber_write( ber, ld->ld_options.ldo_peer,
				sizeof(struct sockaddr), 0);
			}
			if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version ==
				LDAP_VERSION2) {
			    char *dn = ld->ld_options.ldo_cldapdn;
			    if (!dn) dn = "";
			    err = ber_printf( ber, "{isti",  /* '}' */
				++ld->ld_msgid, dn,
				LDAP_REQ_ABANDON, msgid );
			} else
#endif
			{
			    /* create a message to send */
			    err = ber_printf( ber, "{iti",  /* '}' */
				++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, /*{*/ "N}" );

					if( err == -1 ) {
						/* encoding error */
						ld->ld_errno = LDAP_ENCODING_ERROR;
					}
				}
			}

			if ( err == -1 ) {
				ber_free( ber, 1 );

			} else {
				/* send the message */
				if ( lr != NULL ) {
					sb = lr->lr_conn->lconn_sb;
				} else {
					sb = ld->ld_sb;
				}

				if ( ber_flush( sb, ber, 1 ) != 0 ) {
					ld->ld_errno = LDAP_SERVER_DOWN;
					err = -1;
				} else {
					err = 0;
				}
			}
		}
	}

	if ( lr != NULL ) {
		if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
			ldap_free_connection( ld, lr->lr_conn, 0, 1 );
		}
		if ( origid == msgid ) {
			ldap_free_request( ld, lr );
		}
	}

	i = 0;
	if ( ld->ld_abandoned != NULL ) {
		for ( ; ld->ld_abandoned[i] != -1; i++ )
			;	/* NULL */
	}

	old_abandon = ld->ld_abandoned;

	ld->ld_abandoned = (ber_int_t *) LDAP_REALLOC( (char *)
		ld->ld_abandoned, (i + 2) * sizeof(ber_int_t) );
		
	if ( ld->ld_abandoned == NULL ) {
		ld->ld_abandoned = old_abandon;
		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 );
}
Пример #10
0
/*
 * Abandon all outstanding requests for msgid (included child requests
 * spawned when chasing referrals).  This function calls itself recursively.
 * No locking is done is this function so it must be done by the caller.
 * Returns an LDAP error code and sets it in LDAP *ld as well
 */
static int do_abandon(LDAP *ld, int origid, int msgid,
                      LDAPControl **serverctrls, LDAPControl **clientctrls) {
  BerElement *ber;
  int i, bererr, lderr, sendabandon;
  LDAPRequest *lr = NULL;

  /*
   * An abandon request looks like this:
   * AbandonRequest ::= MessageID
   */
  LDAPDebug(LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n", origid, msgid,
            0);

  /* optimistic */
  lderr = LDAP_SUCCESS;

  /*
   * Find the request that we are abandoning.  Don't send an
   * abandon message unless there is something to abandon.
   */
  sendabandon = 0;
  for (lr = ld->ld_requests; lr != NULL; lr = lr->lr_next) {
    if (lr->lr_msgid == msgid) { /* this message */
      if (origid == msgid && lr->lr_parent != NULL) {
        /* don't let caller abandon child requests! */
        lderr = LDAP_PARAM_ERROR;
        goto set_errorcode_and_return;
      }
      if (lr->lr_status == LDAP_REQST_INPROGRESS) {
        /*
         * We only need to send an abandon message if
         * the request is in progress.
         */
        sendabandon = 1;
      }
      break;
    }
    if (lr->lr_origid == msgid) { /* child:  abandon it */
      (void)do_abandon(ld, msgid, lr->lr_msgid, serverctrls, clientctrls);
      /* we ignore errors from child abandons... */
    }
  }

  if (ldap_msgdelete(ld, msgid) == 0) {
    /* we had all the results and deleted them */
    goto set_errorcode_and_return;
  }

  if (lr != NULL && sendabandon) {
    /* create a message to send */
    if ((lderr = nsldapi_alloc_ber_with_options(ld, &ber)) == LDAP_SUCCESS) {
      int abandon_msgid;

      LDAP_MUTEX_LOCK(ld, LDAP_MSGID_LOCK);
      abandon_msgid = ++ld->ld_msgid;
      LDAP_MUTEX_UNLOCK(ld, LDAP_MSGID_LOCK);
#ifdef CLDAP
      if (ld->ld_dbp->sb_naddr > 0) {
        bererr = ber_printf(ber, "{isti", abandon_msgid, ld->ld_cldapdn,
                            LDAP_REQ_ABANDON, msgid);
      } else {
#endif /* CLDAP */
        bererr =
            ber_printf(ber, "{iti", abandon_msgid, LDAP_REQ_ABANDON, msgid);
#ifdef CLDAP
      }
#endif /* CLDAP */

      if (bererr == -1 || (lderr = nsldapi_put_controls(ld, serverctrls, 1,
                                                        ber)) != LDAP_SUCCESS) {
        lderr = LDAP_ENCODING_ERROR;
        ber_free(ber, 1);
      } else {
        /* try to send the message */
        lderr =
            nsldapi_send_abandon_message(ld, lr->lr_conn, ber, abandon_msgid);
      }
    }
  }

  if (lr != NULL) {
    /*
     * Always call nsldapi_free_connection() so that the connection's
     * ref count is correctly decremented.  It is OK to always pass
     * 1 for the "unbind" parameter because doing so will only affect
     * connections that resulted from a child request (because the
     * default connection's ref count never goes to zero).
     */
    nsldapi_free_connection(ld, lr->lr_conn, NULL, NULL, 0 /* do not force */,
                            1 /* send unbind before closing */);

    /*
     * Free the entire request chain if we finished abandoning everything.
     */
    if (origid == msgid) {
      nsldapi_free_request(ld, lr, 0);
    }
  }

  /*
   * Record the abandoned message ID (used to discard any server responses
   * that arrive later).
   */
  LDAP_MUTEX_LOCK(ld, LDAP_ABANDON_LOCK);
  if (ld->ld_abandoned == NULL) {
    if ((ld->ld_abandoned = (int *)NSLDAPI_MALLOC(2 * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
    i = 0;
  } else {
    for (i = 0; ld->ld_abandoned[i] != -1; i++)
      ; /* NULL */
    if ((ld->ld_abandoned = (int *)NSLDAPI_REALLOC(
             (char *)ld->ld_abandoned, (i + 2) * sizeof(int))) == NULL) {
      lderr = LDAP_NO_MEMORY;
      LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);
      goto set_errorcode_and_return;
    }
  }
  ld->ld_abandoned[i] = msgid;
  ld->ld_abandoned[i + 1] = -1;
  LDAP_MUTEX_UNLOCK(ld, LDAP_ABANDON_LOCK);

set_errorcode_and_return:
  LDAP_SET_LDERRNO(ld, lderr, NULL, NULL);
  return (lderr);
}