Beispiel #1
0
static int
default_mr_filter_match(void *obj, Slapi_Entry *e, Slapi_Attr *attr)
{
/* returns:  0  filter matched
 *	    -1  filter did not match
 *	    >0  an LDAP error code
 */
	int rc = -1;
	struct mr_private* mrpriv = (struct mr_private*)obj;
	
	/* In case SLAPI_PLUGIN_OBJECT is not set, mrpriv may be NULL */
	if (mrpriv == NULL)
		return rc;
	
    for (; (rc == -1) && (attr != NULL); slapi_entry_next_attr(e, attr, &attr)) {
		char* type = NULL;
		if (!slapi_attr_get_type (attr, &type) && type != NULL &&
			!slapi_attr_type_cmp ((const char *)mrpriv->type, type, 2/*match subtypes*/)) {
			Slapi_Value **vals = attr_get_present_values(attr);
#ifdef SUPPORT_MR_SUBSTRING_MATCHING
			if (mrpriv->ftype == LDAP_FILTER_SUBSTRINGS) {
				rc = (*mrpriv->match_fn)(pb, mrpriv->initial, mrpriv->any, mrpriv->final, vals);
			}
#endif
			rc = (*mrpriv->match_fn)(NULL, mrpriv->value, vals, mrpriv->ftype, NULL);
		}
Beispiel #2
0
static int
or_filter_match (void* obj, Slapi_Entry* entry, Slapi_Attr* attr)
/* returns:  0  filter matched
 *	    -1  filter did not match
 *	    >0  an LDAP error code
 */
{
    auto int rc = -1; /* no match */
    auto or_filter_t* or = (or_filter_t*)obj;
    for (; attr != NULL; slapi_entry_next_attr (entry, attr, &attr)) {
	auto char* type = NULL;
	auto struct berval** vals = NULL;

/*
 * XXXmcs 1-March-2001: This code would perform better if it did not make
 * a copy of the values here, but that would require re-writing the code
 * in this file to use Slapi_ValueSet's instead of struct berval **'s
 * (and that is not a small project).
 */
	if (!slapi_attr_get_type (attr, &type) && type != NULL &&
	    !slapi_attr_type_cmp (or->or_type, type, 2/*match subtypes*/) &&
	    !slapi_attr_get_bervals_copy(attr, &vals) && vals != NULL) {

	    if (or->or_op == SLAPI_OP_SUBSTRING) {
		rc = ss_filter_match (or, vals);
	    } else {
		rc = op_filter_match (or, vals);
	    }

	    ber_bvecfree( vals );
	    vals = NULL;
	    if (rc >= 0) break;
	}
    }
    return rc;
}
Beispiel #3
0
int
update_integrity(char **argv, Slapi_DN *origSDN,
                 char *newrDN, Slapi_DN *newsuperior, 
                 int logChanges)
{
    Slapi_PBlock *search_result_pb = NULL;
    Slapi_PBlock *mod_pb = slapi_pblock_new();
    Slapi_Entry  **search_entries = NULL;
    Slapi_DN *sdn = NULL;
    Slapi_Attr *attr = NULL;
    void *node = NULL;
    const char *origDN = slapi_sdn_get_dn(origSDN);
    const char *search_base = NULL;
    char *attrName = NULL;
    char *filter = NULL;
    char *attrs[2];
    int search_result;
    int nval = 0;
    int i, j;
    int rc;

    if ( argv == NULL ){
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
            "referint_postop required config file arguments missing\n" );
        rc = -1;
        goto free_and_return;
    } 
    /*
     *  For now, just putting attributes to keep integrity on in conf file,
     *  until resolve the other timing mode issue
     */
    search_result_pb = slapi_pblock_new();

    /* Search each namingContext in turn */
    for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL;
          sdn = slapi_get_next_suffix( &node, 0 ))
    {
        Slapi_Backend *be = slapi_be_select(sdn);
        search_base = slapi_sdn_get_dn( sdn );

        for(i = 3; argv[i] != NULL; i++){
            filter = slapi_filter_sprintf("(%s=*%s%s)", argv[i], ESC_NEXT_VAL, origDN);
            if ( filter ) {
                /* Need only the current attribute and its subtypes */
                attrs[0] = argv[i];
                attrs[1] = NULL;

                /* Use new search API */
                slapi_pblock_init(search_result_pb);
                slapi_pblock_set(search_result_pb, SLAPI_BACKEND, be);
                slapi_search_internal_set_pb(search_result_pb, search_base, 
                    LDAP_SCOPE_SUBTREE, filter, attrs, 0 /* attrs only */,
                    NULL, NULL, referint_plugin_identity, 0);
                slapi_search_internal_pb(search_result_pb);
  
                slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result);

                /* if search successfull then do integrity update */
                if(search_result == LDAP_SUCCESS)
                {
                    slapi_pblock_get(search_result_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
                                     &search_entries);

                    for(j = 0; search_entries[j] != NULL; j++){
                        attr = NULL;
                        attrName = NULL;
                        /*
                         *  Loop over all the attributes of the entry and search
                         *  for the integrity attribute and its subtypes
                         */
                        for (slapi_entry_first_attr(search_entries[j], &attr); attr; 
                             slapi_entry_next_attr(search_entries[j], attr, &attr))
                        {
                            /*
                             *  Take into account only the subtypes of the attribute
                             *  in argv[i] having the necessary value  - origDN
                             */
                            slapi_attr_get_type(attr, &attrName);
                            if (slapi_attr_type_cmp(argv[i], attrName,
                                                    SLAPI_TYPE_CMP_SUBTYPE) == 0)
                            {
                                nval = 0;
                                slapi_attr_get_numvalues(attr, &nval);
                                /* 
                                 * We want to reduce the "modify" call as much as
                                 * possible. But if an entry contains 1000s of 
                                 * attributes which need to be updated by the 
                                 * referint plugin (e.g., a group containing 1000s 
                                 * of members), we want to avoid to allocate too 
                                 * many mods * in one "modify" call.
                                 * This is a compromise: If an attribute type has
                                 * more than 128 values, we update the attribute 
                                 * value one by one. Otherwise, update all values
                                 * in one "modify" call.
                                 */
                                if (nval > 128) {
                                    rc = _update_one_per_mod(
                                         slapi_entry_get_sdn(search_entries[j]),
                                         attr, attrName, origSDN, newrDN, 
                                         slapi_sdn_get_dn(newsuperior),
                                         mod_pb);
                                } else {
                                    rc = _update_all_per_mod(
                                         slapi_entry_get_sdn(search_entries[j]),
                                         attr, attrName, origSDN, newrDN, 
                                         slapi_sdn_get_dn(newsuperior),
                                         mod_pb);
                                }
                                /* Should we stop if one modify returns an error? */
                            }
                        }
                    }
                } else {
                    if (isFatalSearchError(search_result)){
                        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "update_integrity search (base=%s filter=%s) returned "
                            "error %d\n", search_base, filter, search_result);
                        rc = -1;
                        goto free_and_return;
                    }
                }
                slapi_ch_free_string(&filter);
            }
            slapi_free_search_results_internal(search_result_pb);
        }
    }
    /* if got here, then everything good rc = 0 */
    rc = 0;

free_and_return:
    /* free filter and search_results_pb */
    slapi_ch_free_string(&filter);

    slapi_pblock_destroy(mod_pb);
    if (search_result_pb) {
        slapi_free_search_results_internal(search_result_pb);
        slapi_pblock_destroy(search_result_pb);
    }
 
    return(rc);
}
Beispiel #4
0
/*
 * preop_modify - pre-operation plug-in for modify
 */
static int
preop_modify(Slapi_PBlock *pb)
{

  int result = LDAP_SUCCESS;
  Slapi_PBlock *spb = NULL;
  LDAPMod **checkmods = NULL;
  int checkmodsCapacity = 0;
  char *errtext = NULL;
  char *attrName = NULL;

#ifdef DEBUG
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
      "MODIFY begin\n");
#endif

  BEGIN
    int err;
    char *markerObjectClass=NULL;
    char *requiredObjectClass=NULL;
    LDAPMod **mods;
    int modcount = 0;
    int ii;
    LDAPMod *mod;
    Slapi_DN *sdn = NULL;
    int isupdatedn;
    int argc;
    char **argv = NULL;

    /*
     * If this is a replication update, just be a noop.
     */
    err = slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &isupdatedn);
    if (err) { result = uid_op_error(60); break; }
    if (isupdatedn)
    {
      break;
    }

    /*
     * Get the arguments
     */
        result = getArguments(pb, &attrName, &markerObjectClass,
                                                  &requiredObjectClass);
        if (UNTAGGED_PARAMETER == result)
        {
          result = LDAP_SUCCESS;
          /* Statically defined subtrees to monitor */
          err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
          if (err) { result = uid_op_error(53); break; }

          err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
          if (err) { result = uid_op_error(54); break; }
          argc--; /* First argument was attribute name */
          argv++;
        } else if (0 != result)
        {
          break;
        }

    err = slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
    if (err) { result = uid_op_error(61); break; }

    /* There may be more than one mod that matches e.g.
       changetype: modify
       delete: uid
       uid: balster1950
       -
       add: uid
       uid: scottg
       
       So, we need to first find all mods that contain the attribute
       which are add or replace ops and are bvalue encoded
    */
    /* find out how many mods meet this criteria */
    for(;*mods;mods++)
    {
        mod = *mods;
        if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod contains target attr */
            (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is bval encoded (not string val) */
            (mod->mod_bvalues && mod->mod_bvalues[0]) && /* mod actually contains some values */
            (SLAPI_IS_MOD_ADD(mod->mod_op) || /* mod is add */
             SLAPI_IS_MOD_REPLACE(mod->mod_op))) /* mod is replace */
        {
          addMod(&checkmods, &checkmodsCapacity, &modcount, mod);
        }
    }
    if (modcount == 0) {
        break; /* no mods to check, we are done */
    }

    /* Get the target DN */
    err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &sdn);
    if (err) { result = uid_op_error(11); break; }

    /*
     * Check if it has the required object class
     */
    if (requiredObjectClass &&
        !(spb = dnHasObjectClass(sdn, requiredObjectClass))) {
        break;
    }

    /*
     * Passed all the requirements - this is an operation we
     * need to enforce uniqueness on. Now find all parent entries
     * with the marker object class, and do a search for each one.
     */
    /*
     * stop checking at first mod that fails the check
     */
    for (ii = 0; (result == 0) && (ii < modcount); ++ii)
    {
        mod = checkmods[ii];
        if (NULL != markerObjectClass)
        {
            /* Subtree defined by location of marker object class */
            result = findSubtreeAndSearch(sdn, attrName, NULL, 
                                          mod->mod_bvalues, requiredObjectClass,
                                          sdn, markerObjectClass);
        } else
        {
            /* Subtrees listed on invocation line */
            result = searchAllSubtrees(argc, argv, attrName, NULL,
                                       mod->mod_bvalues, requiredObjectClass, sdn);
        }
    }
  END

  slapi_ch_free((void **)&checkmods);
  freePblock(spb);
 if (result)
  {
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
      "MODIFY result %d\n", result);

    if (result == LDAP_CONSTRAINT_VIOLATION) {
      errtext = slapi_ch_smprintf(moreInfo, attrName);
    } else {
      errtext = slapi_ch_strdup("Error checking for attribute uniqueness.");
    }

    slapi_send_ldap_result(pb, result, 0, errtext, 0, 0);

    slapi_ch_free_string(&errtext);
  }

  return (result==LDAP_SUCCESS)?0:-1;

}
Beispiel #5
0
/*
 * aclanom_match_profile
 *	Look at the anonymous profile and see if we can use it or not.
 *
 *
 *	Inputs:
 *		Slapi_Pblock			- The Pblock
 *		Slapi_Entry *e			- The entry for which we are asking permission.
 *		char *attr			- Attribute name
 *		int  access			- access type
 *
 *	Return:
 *		LDAP_SUCCESS ( 0 )		- acess is allowed.
 *		LDAP_INSUFFICIENT_ACCESS (50 )  - access denied.
 *		-1			        - didn't match the targets
 *
 * Assumptions:
 * 	The caller of this module has to make sure that the client is 
 *	an anonymous client.
 */
int
aclanom_match_profile (Slapi_PBlock *pb, struct acl_pblock *aclpb, Slapi_Entry *e,
						char *attr, int access ) 
{

	struct	anom_profile	*a_profile;
	int						result, i, k;
	char					**destArray;
	int						tmatched = 0;
	int						loglevel;
	struct scoped_entry_anominfo *s_e_anominfo =
			&aclpb->aclpb_scoped_entry_anominfo;

	loglevel = slapi_is_loglevel_set(SLAPI_LOG_ACL) ? SLAPI_LOG_ACL : SLAPI_LOG_ACLSUMMARY;

	/* WE are only interested for READ/SEARCH  */
	if (  !(access & ( SLAPI_ACL_SEARCH | SLAPI_ACL_READ)) )
		return -1;

	/* If we are here means, the client is doing a anonymous read/search */
	if ((a_profile = acl_anom_profile) == NULL ) {
		return -1;
	}		

	ANOM_LOCK_READ ();
	/* Check the signature first */
	if ( a_profile->anom_signature != acl_get_aclsignature () ) {
		/* Need to regenrate the signature.
	 	 * Need a WRITE lock to generate the anom profile  -
	 	 * which is obtained in acl__gen_anom_user_profile (). Since
	 	 * I don't have upgrade lock -- I have to do this way.
	 	 */
		ANOM_UNLOCK_READ ();
		aclanom_gen_anomProfile (DO_TAKE_ACLCACHE_READLOCK);
		aclanom_get_suffix_info(e, aclpb );
		ANOM_LOCK_READ ();
	}

	/* doing this early saves use a malloc/free/normalize cost */
	if ( !a_profile->anom_numacls ) {
		ANOM_UNLOCK_READ ();
		return -1;
	}

	result = LDAP_INSUFFICIENT_ACCESS;

	for ( k=0; k<s_e_anominfo->anom_e_nummatched; k++ ) {
		short	matched = 0;
		short	j = 0;	
	
		i = s_e_anominfo->anom_e_targetInfo[k];
	
		/* Check for right */
		if ( !(a_profile->anom_targetinfo[i].anom_access & access) )
			continue;
		
		/*
		 * XXX rbyrne Don't really understand the role of this
		 * but not causing any obvious bugs...get back to it.
		*/		
		tmatched++;
		
		if ( attr == NULL ) {
			result = LDAP_SUCCESS;
			break;
		}

		destArray = a_profile->anom_targetinfo[i].anom_targetAttrs;
		while ( destArray[j] ) {
			if ( strcasecmp ( destArray[j], "*") == 0 ||
				slapi_attr_type_cmp ( attr, destArray[j], 1 ) == 0 ) {
				matched = 1;
				break;
			}
			j++;
		}
		
		if ( a_profile->anom_targetinfo[i].anom_type  & ACI_TARGET_ATTR_NOT )
			result = matched ? LDAP_INSUFFICIENT_ACCESS : LDAP_SUCCESS;
		else 
			result = matched ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
	
		if ( result == LDAP_SUCCESS )
			break;
	} /* for */

	if ( slapi_is_loglevel_set(loglevel) ) {
		char					*ndn = NULL;
		Slapi_Operation			*op = NULL;
		PRUint64 o_connid = 0xffffffffffffffff; /* no op */
		int o_opid = -1; /* no op */
 
		ndn = slapi_entry_get_ndn ( e ) ;
		slapi_pblock_get(pb, SLAPI_OPERATION, &op);
		if (op) {
			o_connid = op->o_connid;
			o_opid = op->o_opid;
		}

		if ( result == LDAP_SUCCESS) {
			const char				*aci_ndn;
			aci_ndn = slapi_sdn_get_ndn (acl_anom_profile->anom_targetinfo[i].anom_target);
			if (access & SLAPI_ACL_MODDN) {
				slapi_log_err(loglevel, plugin_name, 
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) (from %s) to anonymous: acidn=\"%s\"\n",
					o_connid, o_opid,
					ndn,
					attr ? attr:"NULL",
					aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL",
					aci_ndn);
				
			} else {
				slapi_log_err(loglevel, plugin_name, 
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) to anonymous: acidn=\"%s\"\n",
					o_connid, o_opid,
					ndn,
					attr ? attr:"NULL",
					aci_ndn);
			}
		} else {
			if (access & SLAPI_ACL_MODDN) {
				slapi_log_err(loglevel, plugin_name,
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) (from %s) to anonymous\n",
					o_connid, o_opid,
					ndn, attr ? attr:"NULL" ,
					aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL");
			} else {
				slapi_log_err(loglevel, plugin_name,
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) to anonymous\n",
					o_connid, o_opid,
					ndn, attr ? attr:"NULL" );
			}
		}
	}

	ANOM_UNLOCK_READ ();
	if ( tmatched == 0) 
		return -1;
	else 
		return result;
}