Beispiel #1
0
/*
 * hasObjectClass - read an entry and check if it has a
 *   particular object class value
 * Return:
 *   1 - the entry contains the object class value
 *   0 - the entry doesn't contain the object class value
 */
int
entryHasObjectClass(Slapi_PBlock *pb, Slapi_Entry *e,
					const char *objectClass) {
	Slapi_Attr *attr;
	Slapi_Value *v;
	const struct berval *bv;
	int vhint;

	if ( slapi_entry_attr_find(e, "objectclass", &attr) ) {
		return 0;  /* no objectclass values! */
	}

	/*
	 * Check each of the object class values in turn.
	 */
	for ( vhint = slapi_attr_first_value( attr, &v );
			vhint != -1;
			vhint = slapi_attr_next_value( attr, vhint, &v )) {
		bv = slapi_value_get_berval(v);
		if ( NULL != bv && NULL != bv->bv_val &&
				!strcasecmp(bv->bv_val, objectClass) ) {
			return 1;
		}
	}
	return 0;
}
Beispiel #2
0
/* Pre-operation plug-in function */
int
testpreop_add( Slapi_PBlock *pb )
{
	Slapi_Entry	*e;
	Slapi_Attr	*a;
	Slapi_Value	*v;
	struct berval	**bvals;
	int		i, hint;
	char		*tmp;
	const char	*s;

	/* Get the entry that is about to be added. */
	if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) != 0 ) {
		slapi_log_err(SLAPI_LOG_PLUGIN,
		    "testpreop_add", "Could not get entry\n" );
		return( -1 );
	}

	/* Prepend the name "BOB" to the value of the cn attribute
	   in the entry. */
	if ( slapi_entry_attr_find( e, "cn", &a ) == 0 ) {
		for ( hint = slapi_attr_first_value( a, &v ); hint != -1;
				hint = slapi_attr_next_value( a, hint, &v )) {
			s = slapi_value_get_string( v );
			tmp = (char *) malloc( 5 + strlen( s ));
			strcpy( tmp, "BOB " );
			strcat( tmp + 4, s );
			slapi_value_set_string( v, tmp );
			free( tmp );
		}
	}

	return( 0 );	/* allow the operation to continue */
}
Beispiel #3
0
/*
 * search - search a subtree for entries with a named attribute matching
 *   the list of values.  An entry matching the 'target' DN is
 *   not considered in the search.
 *
 * If 'attr' is NULL, the values are taken from 'values'.
 * If 'attr' is non-NULL, the values are taken from 'attr'.
 *
 * Return:
 *   LDAP_SUCCESS - no matches, or the attribute matches the
 *     target dn.
 *   LDAP_CONSTRAINT_VIOLATION - an entry was found that already
 *     contains the attribute value.
 *   LDAP_OPERATIONS_ERROR - a server failure.
 */
static int
search(Slapi_DN *baseDN, const char *attrName, Slapi_Attr *attr,
  struct berval **values, const char *requiredObjectClass,
  Slapi_DN *target)
{
  int result;

#ifdef DEBUG
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
                    "SEARCH baseDN=%s attr=%s target=%s\n", slapi_sdn_get_dn(baseDN), attrName, 
                    target?slapi_sdn_get_dn(target):"None");
#endif

  result = LDAP_SUCCESS;

  /* If no values, can't possibly be a conflict */
  if ( (Slapi_Attr *)NULL == attr && (struct berval **)NULL == values )
    return result;

  /*
   * Perform the search for each value provided
   *
   * Another possibility would be to search for all the values at once.
   * However, this is more complex (for filter creation) and unique
   * attributes values are probably only changed one at a time anyway.
   */
  if ( (Slapi_Attr *)NULL != attr )
  {
	Slapi_Value	*v = NULL;
	int	vhint = -1;

	for ( vhint = slapi_attr_first_value( attr, &v );
		vhint != -1 && LDAP_SUCCESS == result;
		vhint = slapi_attr_next_value( attr, vhint, &v ))
	{
	  result = search_one_berval(baseDN, attrName,
					slapi_value_get_berval(v),
					requiredObjectClass, target);
	}
  }
  else
  {
	for (;*values != NULL && LDAP_SUCCESS == result; values++)
	{
	  result = search_one_berval(baseDN, attrName, *values, requiredObjectClass,
					target);
	}
  }

#ifdef DEBUG
  slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
    "SEARCH result = %d\n", result);
#endif

  return( result );
}
Beispiel #4
0
LDAPWAStatus
WindowsAuthentication( 
	struct backentry	*e,
    struct berval	*cred
)
{
	Slapi_Attr	*a; 
	Slapi_Value *sval = NULL;
	int iStatus;
	char szNTDomain[MAX_PATH], szNTUsername[MAX_PATH];
	HANDLE	hToken = NULL;
	BOOL bLogonStatus = FALSE;
	int i= -1;
 
	/* Get the NT Domain and username - if the entry has such an attribute */
	if( !e || !e->ep_entry ||
		slapi_entry_attr_find( e->ep_entry, "ntuserdomainid", &a ) != 0)
	{
		return( LDAPWA_NoDomainAttr );
	}

	i= slapi_attr_first_value( a, &sval );
	if(sval==NULL)
	{
		return( LDAPWA_NoDomainAttr );	
	}

    while(i != -1)
	{
		const struct berval *val = slapi_value_get_berval(sval);
		char * colon = NULL;

		if (!val->bv_val || (strlen(val->bv_val) > (MAX_PATH<<1))) {
			LDAPDebug( LDAP_DEBUG_TRACE,
				"WindowsAuthentication => validation FAILED for \"%s\" on NT Domain : "
				"ntuserdomainid attr value too long\n",
				val->bv_val, 0, 0);
			i= slapi_attr_next_value(a, i, &sval);
			continue;
		}
		colon = strchr( val->bv_val, ':' );
		if (!colon || ((colon - val->bv_val)/sizeof(char) > MAX_PATH)) {
			if (!colon) {
				LDAPDebug( LDAP_DEBUG_TRACE,
					"WindowsAuthentication => validation FAILED for \"%s\" on NT Domain : "
					"a colon is missing in ntuserdomainid attr value\n",
					val->bv_val, 0, 0);
			}
			else {
				LDAPDebug( LDAP_DEBUG_TRACE,
					"WindowsAuthentication => validation FAILED for \"%s\" on NT Domain : "
					"domain in ntuserdomainid attr value too long\n",
					val->bv_val, 0, 0);
			}
			i= slapi_attr_next_value(a, i, &sval);
			continue;
		}

		if(( iStatus = GetDomainUsername( val->bv_val, 
										  szNTDomain, 
										  szNTUsername )) != 0) 
		{
			i= slapi_attr_next_value(a, i, &sval);
			continue;
		}

#if !defined( LOGON32_LOGON_NETWORK )
/* This is specified in the WIn32 LogonUser() documentation, but not defined
   in the Visual C++ 4.2 include file winbase.h. A search of the lastest version 
   of this file at www.microsoft.com finds that LOGON32_LOGON_NETWORK == 3.
 */
#define LOGON32_LOGON_NETWORK 3
#endif
		/* Now do the Logon attempt */	
		bLogonStatus = LogonUser( szNTUsername, // string that specifies the user name
								  szNTDomain,   // string that specifies the domain or server
								  cred->bv_val,	// string that specifies the password
								  LOGON32_LOGON_NETWORK, //  the type of logon operation, 
								  LOGON32_PROVIDER_DEFAULT,	 // specifies the logon provider
							      &hToken ); // pointer to variable to receive token handle 
		if( bLogonStatus && hToken ) 
			CloseHandle( hToken );
		
		if( bLogonStatus ) 
		{
			// Successful validation
			LDAPDebug( LDAP_DEBUG_TRACE,
				"WindowsAuthentication => validated \"%s\" on NT Domain \"%s\"\n",
				szNTUsername, szNTDomain, 0 );
			return( LDAPWA_Success );
		}
		else
		{
			LDAPDebug( LDAP_DEBUG_TRACE,
				"WindowsAuthentication => validation FAILED for \"%s\" on NT Domain \"%s\", reason %d\n",
				szNTUsername, szNTDomain, GetLastError() );
			return( LDAPWA_InvalidCredentials );
		}
		i= slapi_attr_next_value(a, i, &sval);
	}
 

	return( LDAPWA_Failure );	

}
Beispiel #5
0
/***************************************************************************
*
* __aclinit_handler
*
*	For each entry, finds if there is any ACL in that entry. If there is
*	then the ACL is processed and stored in the ACL LIST.
*
*
* Input:
*
*
* Returns:
*	None.
*
* Error Handling:
*	If any error found during the ACL generation, the ACL is
*	logged.  Also, set in the callback_data so that caller can act upon it.
*
**************************************************************************/
static int
__aclinit_handler ( Slapi_Entry *e, void *callback_data)	
{
    Slapi_Attr 		*attr;
	aclinit_handler_callback_data_t *call_back_data = 
		(aclinit_handler_callback_data_t*)callback_data;	
	Slapi_DN			*e_sdn;
	int					rv;
	Slapi_Value 		*sval=NULL;

	call_back_data->retCode = 0;		 /* assume success--if there's an error we overwrite it */
    if (e != NULL) {		

		e_sdn = slapi_entry_get_sdn ( e );	

		/*
	 	 * Take the write lock around all the mods--so that
	 	 * other operations will see the acicache either before the whole mod
		 * or after but not, as it was before, during the mod.
		 * This is in line with the LDAP concept of the operation
		 * on the whole entry being the atomic unit.
	 	 * 
		*/
		
		if ( call_back_data->op == ACL_ADD_ACIS ) {
			slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"Adding acis for entry '%s'\n", slapi_sdn_get_dn(e_sdn));
			slapi_entry_attr_find ( e, aci_attr_type, &attr );

			if ( attr ) {
				
				const struct berval	*attrValue;				
				
				int i;
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_LOCK();
				}
				i= slapi_attr_first_value ( attr, &sval );
				while(i != -1) {
		        	attrValue = slapi_value_get_berval(sval);									
					
						if ( 0 != (rv=acllist_insert_aci_needsLock (e_sdn, attrValue))) {
							aclutil_print_err(rv, e_sdn, attrValue, NULL); 

							/* We got an error; Log it  and then march along */
							slapi_log_err(SLAPI_LOG_ERR, plugin_name, 
									  "__aclinit_handler - This  (%s) ACL will not be considered for evaluation"
									  " because of syntax errors.\n", 
									  attrValue->bv_val ? attrValue->bv_val: "NULL");
							call_back_data->retCode = rv;
						}				
					i= slapi_attr_next_value( attr, i, &sval );
				}/* while */
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_UNLOCK();
				}
			}
		} else if (call_back_data->op == ACL_REMOVE_ACIS) {

			/* Here we are deleting the acis. */
				slapi_log_err(SLAPI_LOG_ACL, plugin_name, "__aclinit_handler - Removing acis\n");
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_LOCK();
				}	
				if ( 0 != (rv=acllist_remove_aci_needsLock(e_sdn, NULL))) {
					aclutil_print_err(rv, e_sdn, NULL, NULL); 

					/* We got an error; Log it  and then march along */
					slapi_log_err(SLAPI_LOG_ERR, plugin_name, 
									  "__aclinit_handler - ACLs not deleted from %s\n",
                                      slapi_sdn_get_dn(e_sdn));
					call_back_data->retCode = rv;
				}
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_UNLOCK();
				}
		}
		
	}

	/*
	 * If we get here it's success.
	 * The call_back_data->error is the error code that counts as it's the
	 * one that the original caller will see--this routine is called off a callbacl.
	*/
	
    return ACL_FALSE;	/* "local" error code--it's 0 */
}
Beispiel #6
0
/*
 * update multiple attribute values per _do_modify
 */
static int
_update_all_per_mod(Slapi_DN *entrySDN,      /* DN of the searched entry */
                    Slapi_Attr *attr,        /* referred attribute */
                    char *attrName,
                    Slapi_DN *origDN,        /* original DN that was modified */
                    char *newRDN,            /* new RDN from modrdn */
                    const char *newsuperior, /* new superior from modrdn */
                    Slapi_PBlock *mod_pb)
{
    Slapi_Mods *smods = NULL;
    char *newDN = NULL;
    char **dnParts = NULL;
    char *sval = NULL;
    char *newvalue = NULL;
    char *p = NULL;
    size_t dnlen = 0;
    int rc = 0;
    int nval = 0;

    slapi_attr_get_numvalues(attr, &nval);

    if (NULL == newRDN && NULL == newsuperior) {
        /* in delete mode */
        LDAPMod *mods[2];
        char *values_del[2];
        LDAPMod attribute1;

        /* delete old dn so set that up */
        values_del[0] = (char *)slapi_sdn_get_dn(origDN);
        values_del[1] = NULL;
        attribute1.mod_type = attrName;
        attribute1.mod_op = LDAP_MOD_DELETE;
        attribute1.mod_values = values_del;
        mods[0] = &attribute1;
        /* terminate list of mods. */
        mods[1] = NULL;
        rc = _do_modify(mod_pb, entrySDN, mods);
        if (rc) {
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                "_update_all_per_mod: entry %s: deleting \"%s: %s\" failed (%d)"
                "\n", slapi_sdn_get_dn(entrySDN), attrName, slapi_sdn_get_dn(origDN), rc);
        }
    } else {
        /* in modrdn mode */
        const char *superior = NULL;
        int nval = 0;
        Slapi_Value *v = NULL;

        if (NULL == origDN) {
            slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "_update_all_per_mod: NULL dn was passed\n");
            goto bail;
        }
        /* need to put together rdn into a dn */
        dnParts = slapi_ldap_explode_dn( slapi_sdn_get_dn(origDN), 0 );
        if (NULL == dnParts) {
            slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "_update_all_per_mod: failed to explode dn %s\n",
                            slapi_sdn_get_dn(origDN));
            goto bail;
        }
        if (NULL == newRDN) {
            newRDN = dnParts[0];
        }
        if (newsuperior) {
            superior = newsuperior;
        } else {
            /* do not free superior */
            superior = slapi_dn_find_parent(slapi_sdn_get_dn(origDN));
        }
        /* newRDN and superior are already normalized. */
        newDN = slapi_ch_smprintf("%s,%s", newRDN, superior);
        slapi_dn_ignore_case(newDN);
        /* 
         * Compare the modified dn with the value of 
         * the target attribute of referint to find out
         * the modified dn is the ancestor (case 2) or
         * the value itself (case 1).
         *
         * E.g., 
         * (case 1) 
         * modrdn: uid=A,ou=B,o=C --> uid=A',ou=B',o=C
         *            (origDN)             (newDN)
         * member: uid=A,ou=B,ou=C --> uid=A',ou=B',ou=C
         *            (sval)               (newDN)
         *
         * (case 2) 
         * modrdn: ou=B,o=C --> ou=B',o=C
         *         (origDN)      (newDN)
         * member: uid=A,ou=B,ou=C --> uid=A,ou=B',ou=C
         *         (sval)              (sval' + newDN)
         */
        slapi_attr_get_numvalues(attr, &nval);
        smods = slapi_mods_new();
        slapi_mods_init(smods, 2 * nval + 1);

        for (nval = slapi_attr_first_value(attr, &v);
             nval != -1;
             nval = slapi_attr_next_value(attr, nval, &v)) {
            p = NULL;
            dnlen = 0;

            /* DN syntax, which should be a string */
            sval = slapi_ch_strdup(slapi_value_get_string(v));
            rc = slapi_dn_normalize_case_ext(sval, 0,  &p, &dnlen);
            if (rc == 0) { /* sval is passed in; not terminated */
                *(p + dnlen) = '\0';
                sval = p;
            } else if (rc > 0) {
                slapi_ch_free_string(&sval);
                sval = p;
            }
            /* else: (rc < 0) Ignore the DN normalization error for now. */

            p = PL_strstr(sval, slapi_sdn_get_ndn(origDN));
            if (p == sval) {
                /* (case 1) */
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
                slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newDN);

            } else if (p) {
                /* (case 2) */
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
                *p = '\0';
                newvalue = slapi_ch_smprintf("%s%s", sval, newDN);
                slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newvalue);
                slapi_ch_free_string(&newvalue);
            } 
            /* else: value does not include the modified DN.  Ignore it. */
            slapi_ch_free_string(&sval);
        }
        rc = _do_modify(mod_pb, entrySDN, slapi_mods_get_ldapmods_byref(smods));
        if (rc) {
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                        "_update_all_per_mod: entry %s failed (%d)\n",
                        slapi_sdn_get_dn(entrySDN), rc);
        }

        /* cleanup memory allocated for dnParts and newDN */
        if (dnParts){
            slapi_ldap_value_free(dnParts);
            dnParts = NULL;
        }
        slapi_ch_free_string(&newDN);
        slapi_mods_free(&smods);
    }

bail:
    return rc;
}
Beispiel #7
0
/*
  See if the given entry has an attribute with the given name and the
  given value; if value is NULL, just test for the presence of the given
  attribute; if value is an empty string (i.e. value[0] == 0),
  the first value in the attribute will be copied into the given buffer
  and returned
*/
static int
entry_has_attr_and_value(Slapi_Entry *e, const char *attrname,
						 char *value, size_t valuebufsize )
{
	int retval = 0;
	Slapi_Attr *attr = 0;
	if (!e || !attrname)
		return retval;

	/* see if the entry has the specified attribute name */
	if (!slapi_entry_attr_find(e, attrname, &attr) && attr)
	{
		/* if value is not null, see if the attribute has that
		   value */
		if (!value)
		{
			retval = 1;
		}
		else
		{
			Slapi_Value *v = 0;
			int index = 0;
			for (index = slapi_attr_first_value(attr, &v);
				 v && (index != -1);
				 index = slapi_attr_next_value(attr, index, &v))
			{
				const char *s = slapi_value_get_string(v);
				if (!s)
					continue;

				if (!*value)
				{
					size_t		len = strlen(s);

					if ( len < valuebufsize )
					{
						strcpy(value, s);
						retval = 1;
					}
					else
					{
						slapi_log_error( SLAPI_LOG_FATAL, "bootstrap config",
								"Ignoring extremely large value for"
								" configuration attribute %s"
								" (length=%ld, value=%40.40s...)\n",
								attrname, len, s );
						retval = 0;	/* value is too large: ignore it */
					}
					break;
				}
				else if (!strcasecmp(s, value))
				{
					retval = 1;
					break;
				}
			}
		}
	}

	return retval;
}
Beispiel #8
0
/*
 * memberof_validate_config()
 *
 * Validate the pending changes in the e entry.
 */
int
memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, 
	int *returncode, char *returntext, void *arg)
{
	Slapi_Attr *memberof_attr = NULL;
	Slapi_Attr *group_attr = NULL;
	Slapi_DN *config_sdn = NULL;
	Slapi_DN **include_dn = NULL;
	Slapi_DN **exclude_dn = NULL;
	char *syntaxoid = NULL;
	char *config_dn = NULL;
	char *skip_nested = NULL;
	char *auto_add_oc = NULL;
	char **entry_scopes = NULL;
	char **entry_exclude_scopes = NULL;
	int not_dn_syntax = 0;
	int num_vals = 0;

	*returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */

	/* Make sure both the group attr and the memberOf attr
	 * config atributes are supplied.  We don't care about &attr
	 * here, but slapi_entry_attr_find() requires us to pass it. */
	if (!slapi_entry_attr_find(e, MEMBEROF_GROUP_ATTR, &group_attr) &&
		!slapi_entry_attr_find(e, MEMBEROF_ATTR, &memberof_attr))
	{
		Slapi_Attr *test_attr = NULL;
		Slapi_Value *value = NULL;
		int hint = 0;

		/* Loop through each group attribute to see if the syntax is correct. */
		hint = slapi_attr_first_value(group_attr, &value);
		while (value && (not_dn_syntax == 0))
		{
			/* We need to create an attribute to find the syntax. */
			test_attr = slapi_attr_new();
			slapi_attr_init(test_attr, slapi_value_get_string(value));

			/* Get the syntax OID and see if it's the Distinguished Name or
			 * Name and Optional UID syntax. */
			slapi_attr_get_syntax_oid_copy(test_attr, &syntaxoid );
			not_dn_syntax = strcmp(syntaxoid, DN_SYNTAX_OID) & strcmp(syntaxoid, NAME_OPT_UID_SYNTAX_OID);
			slapi_ch_free_string(&syntaxoid);

			/* Print an error if the current attribute is not using the Distinguished
			 * Name syntax, otherwise get the next group attribute. */
			if (not_dn_syntax)
			{
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"The %s configuration attribute must be set to "
					"an attribute defined to use either the Distinguished "
					"Name or Name and Optional UID syntax. (illegal value: %s)",
					slapi_value_get_string(value), MEMBEROF_GROUP_ATTR);
			}
			else
			{
				hint = slapi_attr_next_value(group_attr, hint, &value);
			}

			/* Free the group attribute. */
			slapi_attr_free(&test_attr);
		}

		if (not_dn_syntax == 0)
		{
			/* Check the syntax of the memberof attribute. */
			slapi_attr_first_value(memberof_attr, &value);
			test_attr = slapi_attr_new();
			slapi_attr_init(test_attr, slapi_value_get_string(value));
			slapi_attr_get_syntax_oid_copy(test_attr, &syntaxoid );
			not_dn_syntax = strcmp(syntaxoid, DN_SYNTAX_OID);
			slapi_ch_free_string(&syntaxoid);
			slapi_attr_free(&test_attr);

			if (not_dn_syntax)
			{
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"The %s configuration attribute must be set to "
					"an attribute defined to use the Distinguished "
					"Name syntax.  (illegal value: %s)",
					slapi_value_get_string(value), MEMBEROF_ATTR);
				goto done;
			}
			else
			{
				*returncode = LDAP_SUCCESS;
			}
		}
	} else {
		PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
			"The %s and %s configuration attributes must be provided",
			MEMBEROF_GROUP_ATTR, MEMBEROF_ATTR); 
		goto done;
	}

	if ((skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR))){
		if(strcasecmp(skip_nested, "on") != 0 && strcasecmp(skip_nested, "off") != 0){
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
				"The %s configuration attribute must be set to "
				"\"on\" or \"off\".  (illegal value: %s)",
				MEMBEROF_SKIP_NESTED_ATTR, skip_nested);
			goto done;
		}
	}

	if ((auto_add_oc = slapi_entry_attr_get_charptr(e, MEMBEROF_AUTO_ADD_OC))){
		char *sup = NULL;

		/* Check if the objectclass exists by looking for its superior oc */
		if((sup = slapi_schema_get_superior_name(auto_add_oc)) == NULL){
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
				"The %s configuration attribute must be set to "
				"to an existing objectclass  (unknown: %s)",
				MEMBEROF_AUTO_ADD_OC, auto_add_oc);
			*returncode = LDAP_UNWILLING_TO_PERFORM;
			goto done;
		} else {
			slapi_ch_free_string(&sup);
		}
	}

	if ((config_dn = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA))){
		/* Now check the shared config attribute, validate it now */

		Slapi_Entry *e = NULL;
		int rc = 0;

		rc = slapi_dn_syntax_check(pb, config_dn, 1);
		if (rc) { /* syntax check failed */
			slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_validate_config - "
					"%s does not contain a valid DN (%s)\n",
					SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_dn);
			*returncode = LDAP_INVALID_DN_SYNTAX;
			goto done;
		}
		config_sdn = slapi_sdn_new_dn_byval(config_dn);

		slapi_search_internal_get_entry(config_sdn, NULL, &e, memberof_get_plugin_id());
		if(e){
			slapi_entry_free(e);
			*returncode = LDAP_SUCCESS;
		} else {
			/* config area does not exist! */
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
								"The %s configuration attribute points to an entry that  "
								"can not be found.  (%s)",
								SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_dn);
			*returncode = LDAP_UNWILLING_TO_PERFORM;
		}
	}
	/*
	 * Check the entry scopes
	 */
	entry_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals);
	if(entry_scopes){
		int i = 0;

		/* Validate the syntax before we create our DN array */
		for (i = 0;i < num_vals; i++){
			if(slapi_dn_syntax_check(pb, entry_scopes[i], 1)){
				/* invalid dn syntax */
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"%s: Invalid DN (%s) for include suffix.",
					MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]);
				slapi_ch_array_free(entry_scopes);
				entry_scopes = NULL;
				theConfig.entryScopeCount = 0;
				*returncode = LDAP_UNWILLING_TO_PERFORM;
				goto done;
			}
		}
		/* Now create our SDN array for conflict checking */
		include_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1);
		for (i = 0;i < num_vals; i++){
			include_dn[i] = slapi_sdn_new_dn_passin(entry_scopes[i]);
		}
	}
	/*
	 * Check and process the entry exclude scopes
	 */
	entry_exclude_scopes =
		slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals);
	if(entry_exclude_scopes){
		int i = 0;

		/* Validate the syntax before we create our DN array */
		for (i = 0;i < num_vals; i++){
			if(slapi_dn_syntax_check(pb, entry_exclude_scopes[i], 1)){
				/* invalid dn syntax */
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"%s: Invalid DN (%s) for exclude suffix.",
					MEMBEROF_PLUGIN_SUBSYSTEM, entry_exclude_scopes[i]);
				slapi_ch_array_free(entry_exclude_scopes);
				entry_exclude_scopes = NULL;
				*returncode = LDAP_UNWILLING_TO_PERFORM;
				goto done;
			}
		}
		/* Now create our SDN array for conflict checking */
		exclude_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
		for (i = 0;i < num_vals; i++){
			exclude_dn[i] = slapi_sdn_new_dn_passin(entry_exclude_scopes[i]);
		}
	}
	/*
	 * Need to do conflict checking
	 */
	if(include_dn && exclude_dn){
		/*
		 * Make sure we haven't mixed the same suffix, and there are no
		 * conflicts between the includes and excludes
		 */
		int i = 0;

		while(include_dn[i]){
			int x = 0;
			while(exclude_dn[x]){
				if(slapi_sdn_compare(include_dn[i], exclude_dn[x] ) == 0)
				{
					/* we have a conflict */
					PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
						"%s: include suffix (%s) is also listed as an exclude suffix list",
						MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i]));
					*returncode = LDAP_UNWILLING_TO_PERFORM;
					goto done;
			   }
			   x++;
			}
			i++;
		}

		/* Check for parent/child conflicts */
		i = 0;
		while(include_dn[i]){
			int x = 0;
			while(exclude_dn[x]){
				if(slapi_sdn_issuffix(include_dn[i], exclude_dn[x]))
				{
					/* we have a conflict */
					PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
						"%s: include suffix (%s) is a child of the exclude suffix(%s)",
						MEMBEROF_PLUGIN_SUBSYSTEM,
						slapi_sdn_get_dn(include_dn[i]),
						slapi_sdn_get_dn(exclude_dn[i]));
					*returncode = LDAP_UNWILLING_TO_PERFORM;
					goto done;
			   }
			   x++;
			}
			i++;
		}
	}

done:
	memberof_free_scope(exclude_dn, &num_vals);
	memberof_free_scope(include_dn,	&num_vals);
	slapi_ch_free((void**)&entry_scopes);
	slapi_ch_free((void**)&entry_exclude_scopes);
	slapi_sdn_free(&config_sdn);
	slapi_ch_free_string(&config_dn);
	slapi_ch_free_string(&skip_nested);
	slapi_ch_free_string(&auto_add_oc);

	if (*returncode != LDAP_SUCCESS)
	{
		return SLAPI_DSE_CALLBACK_ERROR;
	}
	else
	{
		return SLAPI_DSE_CALLBACK_OK;
	}
}
Beispiel #9
0
/* send a single attribute */
static int 
my_ber_printf_attr (BerElement *ber, Slapi_Attr *attr, PRBool deleted)
{
    Slapi_Value *value;
	char *type;
    int i;
    const CSN *csn;
			
    /* First, send the type */
	slapi_attr_get_type(attr, &type);
	BER_DEBUG("{s(type ");
	BER_DEBUG(type);
	BER_DEBUG(")");
	if (ber_printf(ber, "{s", type) == -1) /* Begin sequence for this type */
	{
		goto loser;
	}

	/* Send the attribute deletion CSN if present */
	csn = attr_get_deletion_csn(attr);
    if (csn)
    {
		if (my_ber_printf_csn(ber, csn, CSN_TYPE_ATTRIBUTE_DELETED) == -1)
		{
			goto loser;
		}
    }

    /* only send "is deleted" flag for deleted attributes since it defaults to false */
    if (deleted)
    {
		BER_DEBUG("b(del flag)");
        if (ber_printf (ber, "b", PR_TRUE) == -1)
        {
            goto loser;
        }
    }

	/*
	 * Iterate through all the values. 
     */
	BER_DEBUG("[");
	if (ber_printf(ber, "[") == -1) /* Begin set */
	{
		goto loser;
	}
	
    /* 
     * Process the non-deleted values first.
     */
	i = slapi_attr_first_value(attr, &value);
	while (i != -1)
	{
		if (my_ber_printf_value(ber, type, value, PR_FALSE) == -1)
		{
			goto loser;
		}
		i= slapi_attr_next_value(attr, i, &value);
	}

	/*
 	 * Now iterate over all of the deleted values.
	 */
	i= attr_first_deleted_value(attr, &value);
	while (i != -1)
	{
		if (my_ber_printf_value(ber, type, value, PR_TRUE) == -1)
		{
			goto loser;
		}
		i= attr_next_deleted_value(attr, i, &value);
	}
	BER_DEBUG("]");
	if (ber_printf(ber, "]") == -1) /* End set */
	{
		goto loser;
	}

	BER_DEBUG("}");
    if (ber_printf(ber, "}") == -1) /* End sequence for this type */
	{
		goto loser;
	}

    return 0;
loser:
    return -1;
}