Beispiel #1
0
/*
 * lookup instance names by included suffixes and excluded suffixes.
 *
 * Get instance names associated with the given included suffixes
 * as well as the excluded suffixes.
 * Subtract the excluded instances from the included instance.
 * Assign the result to instances.
 */
int
slapi_lookup_instance_name_by_suffixes(char **included, char **excluded,
									   char ***instances)
{
	char **incl_instances, **excl_instances;
	char **p;
	int rval = -1;

	if (instances == NULL)
		return rval;

	*instances = NULL;
	incl_instances = NULL;
	for (p = included; p && *p; p++) {
		if (slapi_lookup_instance_name_by_suffix(*p, NULL, &incl_instances, 0)
																	< 0)
			return rval;
	}

	excl_instances = NULL;
	for (p = excluded; p && *p; p++) {
		/* okay to be empty */
		slapi_lookup_instance_name_by_suffix(*p, NULL, &excl_instances, 0);
	}

	rval = 0;
	if (excl_instances) {
		charray_subtract(incl_instances, excl_instances, NULL);
		charray_free(excl_instances);
	}
	*instances = incl_instances;
	return rval;
}
Beispiel #2
0
int
_ger_generate_template_entry (
	Slapi_PBlock    *pb
	)
{
	Slapi_Entry	*e = NULL;
	char **gerattrs = NULL;
	char **attrs = NULL;
	char **allowedattrs = NULL;
	char *templateentry = NULL;
	char *object = NULL;
	char *superior = NULL;
	char *p = NULL;
	const char *dn = NULL;
	Slapi_DN *sdn = NULL;
	char *dntype = NULL;
	int siz = 0;
	int len = 0;
	int i = 0;
	int notfirst = 0;
	int rc = LDAP_SUCCESS;

	slapi_pblock_get( pb, SLAPI_SEARCH_GERATTRS, &gerattrs );
	if (NULL == gerattrs)
	{
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
						"_ger_generate_template_entry - Objectclass info is expected "
						"in the attr list, e.g., \"*@person\"\n");
		rc = LDAP_SUCCESS;
		goto bailout;
	}
	for (i = 0; gerattrs && gerattrs[i]; i++)
	{
		object = strchr(gerattrs[i], '@');
		if (NULL != object && '\0' != *(++object))
		{
			break;
		}
	}
	if (NULL == object)
	{
		rc = LDAP_SUCCESS;	/* no objectclass info; ok to return */
		goto bailout;
	}
	/* 
	 * Either @objectclass or @objectclass:dntype is accepted.
	 * If @objectclass, the first MUST attributetype (or the first MAY
	 * attributetype if MUST does not exist) is used for the attribute
	 * type in the leaf RDN.
	 * If @objectclass:dntype, dntype is used for the attribute type in the
	 * leaf RDN.
	 */
	dntype = strchr(object, ':');
	if (dntype) { /* @objectclasse:dntype */
		*dntype++ = '\0';
	}

	attrs = slapi_schema_list_objectclass_attributes(
						(const char *)object, SLAPI_OC_FLAG_REQUIRED);
	allowedattrs = slapi_schema_list_objectclass_attributes(
						(const char *)object, SLAPI_OC_FLAG_ALLOWED);
	charray_merge(&attrs, allowedattrs, 0 /* no copy */);
	slapi_ch_free((void **)&allowedattrs); /* free just allowedattrs */
	if (NULL == attrs) {
		rc = LDAP_SUCCESS;	/* bogus objectclass info; ok to return */
		goto bailout;
	}
	for (i = 0; attrs[i]; i++)
	{
		if (0 == strcasecmp(attrs[i], "objectclass"))
		{
			/* <*attrp>: <object>\n\0 */
			siz += strlen(attrs[i]) + 4 + strlen(object);
		}
		else
		{
			/* <*attrp>: (template_attribute)\n\0 */
			siz += strlen(attrs[i]) + 4 + 20;
		}
	}
	/* get the target dn where the template entry is located */
	slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
	dn = slapi_sdn_get_dn(sdn);
	if (dn)
	{
		/* dn: <attr>=<template_name>,<dn>\n\0 */
		if (dntype) {
			siz += strlen(dntype) + 30 + strlen(object) + strlen(dn);
		} else {
			siz += strlen(attrs[0]) + 30 + strlen(object) + strlen(dn);
		}
	}
	else
	{
		/* dn: <attr>=<template_name>\n\0 */
		if (dntype) {
			siz += strlen(dntype) + 30 + strlen(object);
		} else {
			siz += strlen(attrs[0]) + 30 + strlen(object);
		}
	}
	templateentry = (char *)slapi_ch_malloc(siz);
	if (NULL != dn && strlen(dn) > 0)
	{
		PR_snprintf(templateentry, siz,
		            "dn: %s=template_%s_objectclass,%s\n",
		            dntype?dntype:attrs[0], object, dn);
	}
	else
	{
		PR_snprintf(templateentry, siz,
		            "dn: %s=template_%s_objectclass\n",
		            dntype?dntype:attrs[0], object);
	}
	for (--i; i >= 0; i--)
	{
		len = strlen(templateentry);
		p = templateentry + len;
		if (0 == strcasecmp(attrs[i], "objectclass"))
		{
			PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
		}
		else
		{
			PR_snprintf(p, siz - len, "%s: (template_attribute)\n", attrs[i]);
		}
	}
	charray_free(attrs);

	while ((superior = slapi_schema_get_superior_name(object)) &&
			(0 != strcasecmp(superior, "top")))
	{
		if (notfirst)
		{
			slapi_ch_free_string(&object);
		}
		notfirst = 1;
		object = superior;
		attrs = slapi_schema_list_objectclass_attributes(
						(const char *)superior, SLAPI_OC_FLAG_REQUIRED);
		for (i = 0; attrs && attrs[i]; i++)
		{
			if (0 == strcasecmp(attrs[i], "objectclass"))
			{
				/* <*attrp>: <object>\n\0 */
				siz += strlen(attrs[i]) + 4 + strlen(object);
			}
		}
		templateentry = (char *)slapi_ch_realloc(templateentry, siz);
		for (--i; i >= 0; i--)
		{
			len = strlen(templateentry);
			p = templateentry + len;
			if (0 == strcasecmp(attrs[i], "objectclass"))
			{
				PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
			}
		}
		charray_free(attrs);
	}
	if (notfirst)
	{
		slapi_ch_free_string(&object);
	}
	slapi_ch_free_string(&superior);
	siz += 18; /* objectclass: top\n\0 */
	len = strlen(templateentry);
	templateentry = (char *)slapi_ch_realloc(templateentry, siz);
	p = templateentry + len;
	PR_snprintf(p, siz - len, "objectclass: top\n");

	e = slapi_str2entry(templateentry, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
	/* set the template entry to send the result to clients */
	slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, e);
bailout:
	slapi_ch_free_string(&templateentry);
	return rc;
}
Beispiel #3
0
void
_ger_get_attrs_rights (
	Slapi_PBlock *gerpb,
	Slapi_Entry *e,
	const char *subjectndn,
	char **attrs,
	char **gerstr,
	size_t *gerstrsize,
	size_t *gerstrcap,
	char **errbuf
	)
{
	int isfirstattr = 1;

	/* gerstr was initially allocated with enough space for one more line */
	_append_gerstr(gerstr, gerstrsize, gerstrcap, "attributeLevelRights: ", NULL);

	/* 
	 * If it's stated attribute list is given,
	 * the first attr in the list should not be empty.
	 * Otherwise, it's considered the list is not given.
	 */
	if (attrs && *attrs && (strlen(*attrs) > 0))
	{
		int i = 0;
		char **allattrs = NULL;
		char **opattrs = NULL;
		char **noexpattrs = NULL; /* attrs not to expose */
		char **myattrs = NULL;
		char **thisattr = NULL;
		int hasstar = charray_inlist(attrs, "*");
		int hasplus = charray_inlist(attrs, "+");
		Slapi_Attr *objclasses = NULL;
		Slapi_ValueSet *objclassvals = NULL;
		int isextensibleobj = 0;

		/* get all attrs available for the entry */
		slapi_entry_attr_find(e, "objectclass", &objclasses);
		if (NULL != objclasses) {
			Slapi_Value *v;
			slapi_attr_get_valueset(objclasses, &objclassvals);
			i = slapi_valueset_first_value(objclassvals, &v);
			if (-1 != i)
			{
				const char *ocname = NULL;
				allattrs = slapi_schema_list_objectclass_attributes(
							(const char *)v->bv.bv_val,
							SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED);
				/* check if this entry is an extensble object or not */
				ocname = slapi_value_get_string(v);
				if ( strcasecmp( ocname, "extensibleobject" ) == 0 )
				{
					isextensibleobj = 1;
				}
				/* add "aci" to the allattrs to adjust to do_search */
				charray_add(&allattrs, slapi_attr_syntax_normalize("aci"));
				while (-1 != i)
				{
					i = slapi_valueset_next_value(objclassvals, i, &v);
					if (-1 != i)
					{
						myattrs = slapi_schema_list_objectclass_attributes(
							(const char *)v->bv.bv_val,
							SLAPI_OC_FLAG_REQUIRED|SLAPI_OC_FLAG_ALLOWED);
						/* check if this entry is an extensble object or not */
						ocname = slapi_value_get_string(v);
						if ( strcasecmp( ocname, "extensibleobject" ) == 0 )
						{
							isextensibleobj = 1;
						}
						charray_merge_nodup(&allattrs, myattrs, 1/*copy_strs*/);
						charray_free(myattrs);
					}
				}
			}
			slapi_valueset_free(objclassvals);
		}

		/* get operational attrs */
		opattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_OPATTR);
		noexpattrs = slapi_schema_list_attribute_names(SLAPI_ATTR_FLAG_NOEXPOSE);
		/* subtract no expose attrs from opattrs (e.g., unhashed pw) */
		charray_subtract(opattrs, noexpattrs, NULL);

		if (isextensibleobj)
		{
			for ( i = 0; attrs[i]; i++ )
			{
				if ('\0' == *attrs[i]) {
					continue; /* skip an empty attr */
				}
				_ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i], gerstr, 
								gerstrsize, gerstrcap, isfirstattr, errbuf );
				isfirstattr = 0;
			}
		}
		else
		{
			if (hasstar && hasplus)
			{
				GER_GET_ATTR_RIGHTS(allattrs);
				GER_GET_ATTR_RIGHTS(opattrs);
			}
			else if (hasstar)
			{
				GER_GET_ATTR_RIGHTS(allattrs);
				GER_GET_ATTR_RIGHTA_EXT('*', opattrs, allattrs);
			}
			else if (hasplus)
			{
				GER_GET_ATTR_RIGHTS(opattrs);
				GER_GET_ATTR_RIGHTA_EXT('+', allattrs, opattrs);
			}
			else
			{
				for ( i = 0; attrs[i]; i++ )
				{
					if ('\0' == *attrs[i]) {
						continue; /* skip an empty attr */
					}
					if (charray_inlist(noexpattrs, attrs[i]))
					{
						continue;
					}
					else if (charray_inlist(allattrs, attrs[i]) ||
						charray_inlist(opattrs, attrs[i]) ||
						(0 == strcasecmp(attrs[i], "dn")) ||
						(0 == strcasecmp(attrs[i], "distinguishedName")))
					{
						_ger_get_attr_rights ( gerpb, e, subjectndn, attrs[i],
							gerstr, gerstrsize, gerstrcap, isfirstattr, errbuf );
						isfirstattr = 0;
					}
					else
					{
						/* if the attr does not belong to the entry,
						   "<attr>:none" is returned */
						if (!isfirstattr)
						{
							_append_gerstr(gerstr, gerstrsize, gerstrcap, ", ", NULL);
						}
						_append_gerstr(gerstr, gerstrsize, gerstrcap, attrs[i], ":");
						_append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
						isfirstattr = 0;
					}
				}
			}
		}
		charray_free(allattrs);
		charray_free(opattrs);
	}
	else
	{
		Slapi_Attr *prevattr = NULL, *attr;
		char *type;

		while ( slapi_entry_next_attr ( e, prevattr, &attr ) == 0 )
		{
			if ( ! slapi_attr_flag_is_set (attr, SLAPI_ATTR_FLAG_OPATTR) )
			{
				slapi_attr_get_type ( attr, &type );
				_ger_get_attr_rights ( gerpb, e, subjectndn, type, gerstr,
								gerstrsize, gerstrcap, isfirstattr, errbuf );
				isfirstattr = 0;
			}
			prevattr = attr;
		}
	}

	if ( isfirstattr )
	{
		/* not a single attribute was retrived or specified */
		_append_gerstr(gerstr, gerstrsize, gerstrcap, "*:none", NULL);
	}
	return;
}
Beispiel #4
0
static int
changelog4_create_be()
{
	int i, dir_count = 5;
    Slapi_Backend *rbe;
	slapi_be_config config;
	char *cl_dir = changelog4_get_dir ();
	char *cl_suffix;

    if ( cl_dir == NULL ) {
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, 
						"Error: no directory specified for changelog database.\n");
        return -1;
    }
	
	cl_suffix = changelog4_get_suffix ();

    if ( cl_suffix == NULL ) {
		slapi_ch_free ((void **)&cl_dir);
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, 
						"Error: no suffix specified for changelog database.\n");
        return -1;
    }

	/* setup configuration parameters for backend initialization */   
	config.type			= CHANGELOG_LDBM_TYPE;
	config.suffix		= cl_suffix;
	config.is_private	= 1;	/* yes */ 
	config.log_change	= 0;	/* no */
	config.directives = (slapi_config_directive*)slapi_ch_calloc(
                         dir_count, sizeof(slapi_config_directive));
    config.dir_count  = dir_count;

	for (i = 0; i < dir_count; i++)
	{
		config.directives[i].file_name = "(internal)";
		config.directives[i].lineno	= 0;	
	}

	/* setup indexes */
	config.directives[0].argv = NULL;
	config.directives[0].argc = 3;
	charray_add( &(config.directives[0].argv), slapi_ch_strdup( "index" ));
	charray_add( &(config.directives[0].argv), slapi_ch_strdup( attr_changenumber ));
	charray_add( &(config.directives[0].argv), slapi_ch_strdup( "eq" ));

    /* Set up the database directory */
    config.directives[1].argv = NULL;
    config.directives[1].argc = 2;
    charray_add( &(config.directives[1].argv), slapi_ch_strdup( "directory" ));
    charray_add( &(config.directives[1].argv), slapi_ch_strdup( cl_dir ));

    /* Override the entry cache size */
    config.directives[2].argv = NULL;
    config.directives[2].argc = 2;
    charray_add( &(config.directives[2].argv), slapi_ch_strdup( "cachesize" ));
    charray_add( &(config.directives[2].argv), slapi_ch_strdup( "10" ));

    /* Override the database cache size */
    config.directives[3].argv = NULL;
    config.directives[3].argc = 2;
    charray_add( &(config.directives[3].argv), slapi_ch_strdup( "dbcachesize" ));
    charray_add( &(config.directives[3].argv), slapi_ch_strdup( "1000000" ));
   
    /* Override the allids threshold */
    config.directives[4].argv = NULL;
    config.directives[4].argc = 2;
    charray_add( &(config.directives[4].argv), slapi_ch_strdup( "allidsthreshold" ));
	/* assumes sizeof(int) >= 32 bits */
    charray_add( &(config.directives[4].argv), slapi_ch_strdup( "2147483647" )); 

	/* rbe = slapi_be_create_instance(&config, LDBM_TYPE); */
	rbe= NULL;

	/* free memory allocated to argv */
	for (i = 0; i < dir_count; i++)
	{
		charray_free (config.directives[i].argv);
	}

	slapi_ch_free ((void **)&config.directives);
	slapi_ch_free ((void **)&cl_dir);
	slapi_ch_free ((void **)&cl_suffix);
 
	if (rbe == NULL)
	{
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, 
						"Error: failed to create changelog backend. "
						"Replication disabled.\n");
		return -1;
	}

    set_repl_backend (rbe);

	changelog4_init_trimming ();

	return 0;   
}
Beispiel #5
0
/*
 * Thread routine for sending search results to a client
 * which is persistently waiting for them.
 *
 * This routine will terminate when either (a) the ps_complete
 * flag is set, or (b) the associated operation is abandoned.
 * In any case, the thread won't notice until it wakes from
 * sleeping on the ps_list condition variable, so it needs
 * to be awakened.
 */
static void
ps_send_results( void *arg )
{
    PSearch *ps = (PSearch *)arg;
	PSEQNode *peq, *peqnext;
	struct slapi_filter *filter = 0;
	char *base = NULL;
	Slapi_DN *sdn = NULL;
	char *fstr = NULL;
	char **pbattrs = NULL;
	int conn_acq_flag = 0;
    
    g_incr_active_threadcnt();

    /* need to acquire a reference to this connection so that it will not
       be released or cleaned up out from under us */
    PR_Lock( ps->ps_pblock->pb_conn->c_mutex );
    conn_acq_flag = connection_acquire_nolock(ps->ps_pblock->pb_conn);    
    PR_Unlock( ps->ps_pblock->pb_conn->c_mutex );

	if (conn_acq_flag) {
		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d Could not acquire the connection - psearch aborted\n",
						ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
	}

    PR_Lock( psearch_list->pl_cvarlock );

    while ( (conn_acq_flag == 0) && !ps->ps_complete ) {
	/* Check for an abandoned operation */
	if ( ps->ps_pblock->pb_op == NULL || slapi_op_abandoned( ps->ps_pblock ) ) {
		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d The operation has been abandoned\n",
						ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
	    break;
	}
	if ( NULL == ps->ps_eq_head ) {
	    /* Nothing to do */
	    PR_WaitCondVar( psearch_list->pl_cvar, PR_INTERVAL_NO_TIMEOUT );
	} else {
	    /* dequeue the item */
	    int		attrsonly;
	    char	**attrs;
	    LDAPControl	**ectrls;
	    Slapi_Entry	*ec;
		Slapi_Filter	*f = NULL;
		
	    PR_Lock( ps->ps_lock );

		peq = ps->ps_eq_head;
		ps->ps_eq_head = peq->pe_next;
	    if ( NULL == ps->ps_eq_head ) {
			ps->ps_eq_tail = NULL;
	    }

	    PR_Unlock( ps->ps_lock );

	    /* Get all the information we need to send the result */
	    ec = peq->pe_entry;
	    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRS, &attrs );
	    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
	    if ( !ps->ps_send_entchg_controls || peq->pe_ctrls[0] == NULL ) {
		ectrls = NULL;
	    } else {
		ectrls = peq->pe_ctrls;
	    }

	    /*
	     * Send the result.  Since send_ldap_search_entry can block for
	     * up to 30 minutes, we relinquish all locks before calling it.
	     */
	    PR_Unlock(psearch_list->pl_cvarlock);

		/*
		 * The entry is in the right scope and matches the filter
		 * but we need to redo the filter test here to check access
		 * controls. See the comments at the slapi_filter_test()
		 * call in ps_service_persistent_searches().		 
		*/
		slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_FILTER, &f );			

		/* See if the entry meets the filter and ACL criteria */
		if ( slapi_vattr_filter_test( ps->ps_pblock, ec, f,
			    1 /* verify_access */ ) == 0 ) {
			int rc = 0;
	    	slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_RESULT_ENTRY, ec );
	    	rc = send_ldap_search_entry( ps->ps_pblock, ec,
										 ectrls, attrs, attrsonly );
			if (rc) {
				slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
								"conn=%" NSPRIu64 " op=%d Error %d sending entry %s with op status %d\n",
								ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid,
								rc, slapi_entry_get_dn_const(ec), ps->ps_pblock->pb_op->o_status);
			}
		}
	    
		PR_Lock(psearch_list->pl_cvarlock);

		/* Deallocate our wrapper for this entry */
		pe_ch_free( &peq );
	}
    }
    PR_Unlock( psearch_list->pl_cvarlock );
    ps_remove( ps );

    /* indicate the end of search */
    plugin_call_plugins( ps->ps_pblock , SLAPI_PLUGIN_POST_SEARCH_FN );

	/* free things from the pblock that were not free'd in do_search() */
	/* we strdup'd this in search.c - need to free */
	slapi_pblock_get( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, &base );
	slapi_pblock_set( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, NULL );
	slapi_ch_free_string(&base);

	/* Free SLAPI_SEARCH_* before deleting op since those are held by op */
	slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, &sdn );
	slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, NULL );
	slapi_sdn_free(&sdn);

    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_STRFILTER, &fstr );
    slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_STRFILTER, NULL );
	slapi_ch_free_string(&fstr);

    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRS, &pbattrs );
    slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_ATTRS, NULL );
	if ( pbattrs != NULL )
	{
		charray_free( pbattrs );
	}
	
	slapi_pblock_get(ps->ps_pblock, SLAPI_SEARCH_FILTER, &filter );
	slapi_pblock_set(ps->ps_pblock, SLAPI_SEARCH_FILTER, NULL );
	slapi_filter_free(filter, 1);

    /* Clean up the connection structure */
    PR_Lock( ps->ps_pblock->pb_conn->c_mutex );

	slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
					"conn=%" NSPRIu64 " op=%d Releasing the connection and operation\n",
					ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
    /* Delete this op from the connection's list */
    connection_remove_operation( ps->ps_pblock->pb_conn, ps->ps_pblock->pb_op );
    operation_free(&(ps->ps_pblock->pb_op),ps->ps_pblock->pb_conn);
    ps->ps_pblock->pb_op=NULL;

    /* Decrement the connection refcnt */
    if (conn_acq_flag == 0) { /* we acquired it, so release it */
	connection_release_nolock (ps->ps_pblock->pb_conn);
    }
    PR_Unlock( ps->ps_pblock->pb_conn->c_mutex );

    PR_DestroyLock ( ps->ps_lock );
    ps->ps_lock = NULL;

    slapi_ch_free((void **) &ps->ps_pblock );
	for ( peq = ps->ps_eq_head; peq; peq = peqnext) {
		peqnext = peq->pe_next;
		pe_ch_free( &peq );
	}
    slapi_ch_free((void **) &ps );
    g_decr_active_threadcnt();
}