Beispiel #1
0
int
sync_send_entry_from_changelog(Slapi_PBlock *pb,int chg_req, char *uniqueid)
{
	Slapi_Entry *db_entry = NULL;
	int chg_type = LDAP_SYNC_ADD;
	int rv;
	Slapi_PBlock *search_pb = NULL;
    	Slapi_Entry **entries = NULL;
	char *origbase;
	char *filter = slapi_ch_smprintf("(nsuniqueid=%s)",uniqueid);

	slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET_DN, &origbase );
	search_pb = slapi_pblock_new();
    	slapi_search_internal_set_pb(search_pb, origbase,
           				LDAP_SCOPE_SUBTREE, filter,
            				NULL, 0, NULL, NULL, plugin_get_default_component_id(), 0);
 	slapi_search_internal_pb(search_pb);
	slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rv);
	if ( rv == LDAP_SUCCESS) {
		slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
    		if (entries)
			db_entry = *entries; /* there can only be one */
	}

	if (db_entry && sync_is_entry_in_scope(pb, db_entry)) {
		LDAPControl **ctrl = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *));
		sync_create_state_control(db_entry, &ctrl[0], chg_type, NULL);
		slapi_send_ldap_search_entry (pb, db_entry, ctrl, NULL, 0);
		ldap_controls_free(ctrl);
	}
	slapi_free_search_results_internal(search_pb);
	slapi_pblock_destroy(search_pb);
	slapi_ch_free((void **)&filter);
	return (0);
}
Beispiel #2
0
/*
 * Access the database sequentially.
 * There are 4 ways to call this routine.  In each case, the equality index
 * for "attrname" is consulted:
 *  1) If the SLAPI_SEQ_TYPE parameter is SLAPI_SEQ_FIRST, then this routine
 *     will find the smallest key greater than or equal to the SLAPI_SEQ_VAL
 *     parameter, and return all entries that key's IDList.  If SLAPI_SEQ_VAL
 *     is NULL, then the smallest key is retrieved and the associaated
 *     entries are returned.
 *  2) If the SLAPI_SEQ_TYPE parameter is SLAPI_SEQ_NEXT, then this routine
 *     will find the smallest key strictly greater than the SLAPI_SEQ_VAL
 *     parameter, and return all entries that key's IDList.
 *  3) If the SLAPI_SEQ_TYPE parameter is SLAPI_SEQ_PREV, then this routine
 *     will find the greatest key strictly less than the SLAPI_SEQ_VAL
 *     parameter, and return all entries that key's IDList.
 *  4) If the SLAPI_SEQ_TYPE parameter is SLAPI_SEQ_LAST, then this routine 
 *     will find the largest equality key in the index and return all entries
 *     which match that key.  The SLAPI_SEQ_VAL parameter is ignored.
 */
int
ldbm_back_seq( Slapi_PBlock *pb )
{
	backend         *be;
	ldbm_instance   *inst;
	struct ldbminfo *li;
	IDList          *idl = NULL;
	back_txn        txn = {NULL};
	back_txnid parent_txn;
	struct attrinfo	*ai = NULL;
	DB              *db;
	DBC             *dbc = NULL;
	char *attrname, *val;
	int err = LDAP_SUCCESS;
	int return_value = -1;
	int nentries = 0;
	int retry_count = 0;
	int isroot;
	int type;

	/* Decode arguments */
	slapi_pblock_get( pb, SLAPI_BACKEND, &be);
	slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li );
	slapi_pblock_get( pb, SLAPI_SEQ_TYPE, &type );
	slapi_pblock_get( pb, SLAPI_SEQ_ATTRNAME, &attrname );
	slapi_pblock_get( pb, SLAPI_SEQ_VAL, &val );
	slapi_pblock_get( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
	slapi_pblock_get( pb, SLAPI_TXN, (void **)&parent_txn );

	inst = (ldbm_instance *) be->be_instance_info;

	dblayer_txn_init( li, &txn );
	if (!parent_txn) {
		parent_txn = txn.back_txn_txn;
		slapi_pblock_set( pb, SLAPI_TXN, parent_txn );
	}

	/* Validate arguments */
	if ( type != SLAPI_SEQ_FIRST &&
	     type != SLAPI_SEQ_LAST &&
	     type != SLAPI_SEQ_NEXT &&
	     type != SLAPI_SEQ_PREV )
	{
	    slapi_send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
		    "Bad seq access type", 0, NULL );
	    return( -1 );
	}

	/* get a database */

	ainfo_get( be, attrname, &ai );
	slapi_log_err(SLAPI_LOG_ARGS,
	    "ldbm_back_seq", "indextype: %s indexmask: 0x%x seek type: %d\n",
	    ai->ai_type, ai->ai_indexmask, type );
	if ( ! (INDEX_EQUALITY & ai->ai_indexmask) ) {
		slapi_log_err(SLAPI_LOG_TRACE,
		    "ldbm_back_seq", "caller specified un-indexed attribute %s\n",
			   attrname ? attrname : "");
		slapi_send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
		    "Unindexed seq access type", 0, NULL );
		return -1;
	}

	if ( (return_value = dblayer_get_index_file( be, ai, &db, DBOPEN_CREATE )) != 0 ) {
		slapi_log_err(SLAPI_LOG_ERR,
		    "ldbm_back_seq", "Could not open index file for attribute %s\n",
		    attrname);
		slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL );
		return -1;
	}
retry:
	if (txn.back_txn_txn) {
		dblayer_read_txn_begin(be, parent_txn, &txn);
	}
	/* First, get a database cursor */
	return_value = db->cursor(db, txn.back_txn_txn, &dbc, 0);

	if (0 == return_value)
	{
		DBT data = {0};
		DBT key = {0};
		char little_buffer[SEQ_LITTLE_BUFFER_SIZE];
		char *big_buffer = NULL;
		char keystring = EQ_PREFIX;

		/* Set data */
		data.flags = DB_DBT_MALLOC;

		/* Set up key */
		key.flags = DB_DBT_MALLOC;
		if (NULL == val)
		{
			/* this means, goto the first equality key */
			/* seek to key >= "=" */
			key.data = &keystring;
			key.size = 1;
		}
		else
		{
			size_t key_length = strlen(val) + 2;
			if (key_length <= SEQ_LITTLE_BUFFER_SIZE) {
				key.data = &little_buffer;
			} else {
				big_buffer = slapi_ch_malloc(key_length);
				if (NULL == big_buffer) {
					/* memory allocation failure */
					dblayer_release_index_file( be, ai, db );
					return -1;
				}
				key.data = big_buffer;
			}
			key.size = sprintf(key.data,"%c%s",EQ_PREFIX,val);
		}

		/* decide which type of operation we're being asked to do and do the db bit */
		/* The c_get call always mallocs memory for data.data */
		/* The c_get call mallocs memory for key.data, except for DB_SET */
		/* after this, we leave data containing the retrieved IDL, or NULL if we didn't get it */

		switch (type) {
		case SLAPI_SEQ_FIRST:
			/* if (NULL == val) goto the first equality key ( seek to key >= "=" ) */
			/* else goto the first equality key >= val ( seek to key >= "=val"  )*/
			return_value = dbc->c_get(dbc,&key,&data,DB_SET_RANGE);
			break;
		case SLAPI_SEQ_NEXT:
			/* seek to the indicated =value, then seek to the next entry, */
			return_value = dbc->c_get(dbc,&key,&data,DB_SET);
			if (0 == return_value)
			{
				slapi_ch_free(&(data.data));
				return_value = dbc->c_get(dbc,&key,&data,DB_NEXT);
			}
			else
			{
				/* DB_SET doesn't allocate key data.  Make sure we don't try to free it... */
				key.data= NULL;
			}
			break;
		case SLAPI_SEQ_PREV:
			/* seek to the indicated =value, then seek to the previous entry, */
			return_value = dbc->c_get(dbc,&key,&data,DB_SET);
			if (0 == return_value )
			{
				slapi_ch_free(&(data.data));
				return_value = dbc->c_get(dbc,&key,&data,DB_PREV);
			}
			else
			{
				/* DB_SET doesn't allocate key data.  Make sure we don't try to free it... */
				key.data= NULL;
			}
			break;
		case SLAPI_SEQ_LAST:
			/* seek to the first possible key after all the equality keys (">"), then seek back one */
			{
				keystring = EQ_PREFIX + 1;
				key.data = &keystring;
				key.size = 1;
				return_value = dbc->c_get(dbc,&key,&data,DB_SET_RANGE);
				if ((0 == return_value) || (DB_NOTFOUND == return_value)) {
					slapi_ch_free(&(data.data));
					return_value = dbc->c_get(dbc,&key,&data,DB_PREV); 
				}
			}
			break;
		}

		dbc->c_close(dbc);

		if ((0 == return_value) || (DB_NOTFOUND == return_value)) {
			/* Now check that the key we eventually settled on was an equality key ! */
			if (key.data && *((char*)key.data) == EQ_PREFIX) {
				/* Retrieve the idlist for this key */
				key.flags = 0;
				for (retry_count = 0; retry_count < IDL_FETCH_RETRY_COUNT; retry_count++) {
					err = NEW_IDL_DEFAULT;
					idl_free(&idl);
					idl = idl_fetch( be, db, &key, parent_txn, ai, &err );
					if(err == DB_LOCK_DEADLOCK) {
						ldbm_nasty("ldbm_back_seq", "deadlock retry", 1600, err);
						if (txn.back_txn_txn) {
							/* just in case */
							slapi_ch_free(&(data.data));
							if ((key.data != little_buffer) && (key.data != &keystring)) {
								slapi_ch_free(&(key.data));
							}
							dblayer_read_txn_abort(be, &txn);
							goto retry;
						} else {
							continue;
						}
					} else {
						break;
					}
				}
			}
		} else {
			if (txn.back_txn_txn) {
				dblayer_read_txn_abort(be, &txn);
			}
			if (DB_LOCK_DEADLOCK == return_value) {
				ldbm_nasty("ldbm_back_seq", "deadlock retry", 1601, err);
				/* just in case */
				slapi_ch_free(&(data.data));
				if ((key.data != little_buffer) && (key.data != &keystring)) {
					slapi_ch_free(&(key.data));
				}
				goto retry;
			}
		}
		if(retry_count == IDL_FETCH_RETRY_COUNT) {
			ldbm_nasty("ldbm_back_seq", "Retry count exceeded",1645,err);
		} else if ( err != 0 && err != DB_NOTFOUND ) {
			ldbm_nasty("ldbm_back_seq", "Database error", 1650, err);
		}
		slapi_ch_free( &(data.data) );
		if ( key.data != little_buffer && key.data != &keystring ) {
		    slapi_ch_free( &(key.data) );
		}
		slapi_ch_free_string( &big_buffer );
	}

	/* null idlist means there were no matching keys */
	if ( idl != NULL )
	{
		/*
		 * Step through the IDlist.  For each ID, get the entry
		 * and send it.
		 */
		ID id;
		struct backentry	*e;
		for ( id = idl_firstid( idl ); id != NOID;
			id = idl_nextid( idl, id ))
		{
		    if (( e = id2entry( be, id, &txn, &err )) == NULL )
		    {
				if ( err != LDAP_SUCCESS )
				{
				    slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_seq", "id2entry err %d\n", err);
				}
				slapi_log_err(SLAPI_LOG_ARGS,
					"ldbm_back_seq", "candidate %lu not found\n",
					(u_long)id);
				continue;
		    }
		    if ( slapi_send_ldap_search_entry( pb, e->ep_entry, NULL, NULL, 0 ) == 0 )
		    {
				nentries++;
		    }
		    CACHE_RETURN( &inst->inst_cache, &e );
		}
		idl_free( &idl );
	}
	/* if success finally commit the transaction, otherwise abort if DB_NOTFOUND */
	if(txn.back_txn_txn){
		if (return_value == 0) {
			dblayer_read_txn_commit(be, &txn);
		} else if (DB_NOTFOUND == return_value){
			dblayer_read_txn_abort(be, &txn);
		}
	}

	dblayer_release_index_file( be, ai, db );

	slapi_send_ldap_result( pb, LDAP_SUCCESS == err ? LDAP_SUCCESS : LDAP_OPERATIONS_ERROR, NULL, NULL, nentries, NULL );

	return 0;
}
Beispiel #3
0
static int
nullsuffix_search( Slapi_PBlock *pb )
{
	char			*dn_base, **attrs, *newStr;
	int				scope, sizelimit, timelimit, deref, attrsonly;
	Slapi_Filter	*filter;
	Slapi_DN		*sdn_base;
	int				ldaperr = LDAP_SUCCESS;	/* optimistic */
	int				nentries = 0;	/* entry count */
	int				i;
	Slapi_Operation	*op;
	Slapi_Entry		*e;

	const char *entrystr =
		"dn:cn=Joe Smith,o=Example\n"
		"objectClass: top\n"
		"objectClass: person\n"
		"objectClass: organizationalPerson\n"
		"objectClass: inetOrgPerson\n"
		"cn:Joe Smith\n"
		"sn:Smith\n"
		"uid:jsmith\n"
		"mail:[email protected]\n";
	
	slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_search\n" );
	if( slapi_op_reserved(pb) ){
		return PLUGIN_OPERATION_IGNORED;
	}

	/* get essential search parameters */
	if ( slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &dn_base ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) != 0 ) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"could not get base DN and scope search parameters\n" );
	}
	if ( dn_base == NULL ) {
		dn_base = "";
	}
	sdn_base = slapi_sdn_new_dn_byval( dn_base );
	slapi_pblock_get(pb, SLAPI_OPERATION, &op);

	/* get remaining search parameters */
	if ( slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_ATTRS, &attrs ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly ) != 0 ) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"could not get remaining search parameters\n" );
	}

	if ( slapi_pblock_get( pb, SLAPI_OPERATION, &op ) != 0 ) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"could not get operation\n" );
	} else {
		 slapi_operation_set_flag(op, SLAPI_OP_FLAG_NO_ACCESS_CHECK  );
	}

	/* create a fake entry and send it along */
	newStr = slapi_ch_strdup( entrystr );
	if ( NULL == ( e = slapi_str2entry( newStr,
				SLAPI_STR2ENTRY_ADDRDNVALS
				| SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES ))) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"nullsuffix_search: slapi_str2entry() failed\n" );
	} else {
		slapi_send_ldap_search_entry( pb, e, NULL /* controls */,
				attrs, attrsonly );
		++nentries;
		slapi_entry_free( e );
	}

	slapi_send_ldap_result( pb, ldaperr, NULL, "kilroy was here",
			nentries, NULL );
	slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_search:"
			" handled search based at %s with scope %d; ldaperr=%d\n",
			dn_base, scope, ldaperr );

	slapi_ch_free_string(&newStr);
	slapi_sdn_free(&sdn_base);

	return PLUGIN_OPERATION_HANDLED;
}