示例#1
0
/*
 * Config DSE callback for index entry changes.
 *
 * this function is huge!
 */
int
ldbm_instance_attrcrypt_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
        Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg)
{
    ldbm_instance *inst = (ldbm_instance *)arg;
    Slapi_Attr *attr;
    Slapi_Value *sval;
    const struct berval *attrValue;
    struct attrinfo *ainfo = NULL;
    LDAPMod **mods;
	int i = 0;
	int j = 0;

    returntext[0] = '\0';
    *returncode = LDAP_SUCCESS;
    slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);

    slapi_entry_attr_find(e, "cn", &attr);
    slapi_attr_first_value(attr, &sval);
    attrValue = slapi_value_get_berval(sval);
    ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
    if (NULL == ainfo) {
        return SLAPI_DSE_CALLBACK_ERROR;
    }

    for (i = 0; (mods != NULL) && (mods[i] != NULL); i++) {

        char *config_attr = (char *)mods[i]->mod_type;

		/* There are basically three cases in the modify: 
		 * 1. The attribute was added
		 * 2. The attribute was deleted
		 * 3. The attribute was modified (deleted and added).
		 * Now, of these three, only #3 is legal.
		 * This is because the attribute is mandatory and single-valued in the schema.
		 * We handle this as follows: an add will always replace what's there (if anything).
		 * a delete will remove what's there as long as it matches what's being deleted.
		 * this is to avoid ordering problems with the adds and deletes.
		 */

        if (strcasecmp(config_attr, "nsEncryptionAlgorithm") == 0) {

            if (SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {

                for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) {
                    int cipher = ldbm_attrcrypt_parse_cipher(mods[i]->mod_bvalues[j]->bv_val);
					if (0 == cipher) {
						/* Tried to configure an invalid cipher */
					}
					ldbm_instance_attrcrypt_enable(ainfo,cipher);
                }
                continue;
            }
            if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op)) {
                if ((mods[i]->mod_bvalues == NULL) ||
                    (mods[i]->mod_bvalues[0] == NULL)) {
					/* Not legal */
					return SLAPI_DSE_CALLBACK_ERROR;
                } else {
                    for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) {
						/* Code before here should ensure that we only ever delete something that was already here */
						ldbm_instance_attrcrypt_disable(ainfo);
                    }
                }
                continue;
            }
        }
	}
    return SLAPI_DSE_CALLBACK_OK;
}
示例#2
0
/*
 * Check if we are modifying the config, or changing the shared config entry
 */
int
memberof_shared_config_validate(Slapi_PBlock *pb)
{
	Slapi_Entry *e = 0;
	Slapi_Entry *resulting_e = 0;
	Slapi_Entry *config_entry = NULL;
	Slapi_DN *sdn = NULL;
	Slapi_DN *config_sdn = NULL;
	Slapi_Mods *smods = 0;
	Slapi_Mod *smod = NULL, *nextmod = NULL;
	LDAPMod **mods = NULL;
	char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
	char *configarea_dn = NULL;
	int ret = SLAPI_PLUGIN_SUCCESS;

	slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);

	if (slapi_sdn_compare(sdn, memberof_get_plugin_area()) == 0 ||
	    slapi_sdn_compare(sdn, memberof_get_config_area()) == 0)
	{
		slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e);
		if(e){
			/*
			 * Create a copy of the entry and apply the
			 * mods to create the resulting entry.
			 */
			slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
			smods = slapi_mods_new();
			slapi_mods_init_byref(smods, mods);
			resulting_e = slapi_entry_dup(e);
			if (mods && (slapi_entry_apply_mods(resulting_e, mods) != LDAP_SUCCESS)) {
				/* we don't care about this, the update is invalid and will be caught later */
				goto bail;
			}

			if (slapi_sdn_compare(sdn, memberof_get_plugin_area())){
				/*
				 * This entry is a plugin config area entry, validate it.
				 */
				if( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, resulting_e, &ret, returntext,0)) {
					ret = LDAP_UNWILLING_TO_PERFORM;
				}
			} else {
				/*
				 * This is the memberOf plugin entry, check if we are adding/replacing the
				 * plugin config area.
				 */
				nextmod = slapi_mod_new();
				for (smod = slapi_mods_get_first_smod(smods, nextmod);
					 smod != NULL;
					 smod = slapi_mods_get_next_smod(smods, nextmod) )
				{
					if ( PL_strcasecmp(SLAPI_PLUGIN_SHARED_CONFIG_AREA, slapi_mod_get_type(smod)) == 0 )
					{
						/*
						 * Okay, we are modifying the plugin config area, we only care about
						 * adds and replaces.
						 */
						if(SLAPI_IS_MOD_REPLACE(slapi_mod_get_operation(smod)) ||
						   SLAPI_IS_MOD_ADD(slapi_mod_get_operation(smod)))
						{
						    struct berval *bv = NULL;
						    int rc = 0;

							bv = slapi_mod_get_first_value(smod);
							configarea_dn = slapi_ch_strdup(bv->bv_val);
							if(configarea_dn){
								/* Check the DN syntax */
								rc = slapi_dn_syntax_check(pb, configarea_dn, 1);
								if (rc) { /* syntax check failed */
									PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
										"%s does not contain a valid DN (%s)",
										SLAPI_PLUGIN_SHARED_CONFIG_AREA, configarea_dn);
									ret = LDAP_UNWILLING_TO_PERFORM;
									goto bail;
								}

								/* Check if the plugin config area entry exists */
								if((config_sdn = slapi_sdn_new_dn_byval(configarea_dn))){
									rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry,
										memberof_get_plugin_id());
									if(config_entry){
										int err = 0;
										/*
										 * Validate the settings from the new config area.
										 */
										if ( memberof_validate_config(pb, NULL, config_entry, &err, returntext,0)
											 == SLAPI_DSE_CALLBACK_ERROR )
										{
											ret = LDAP_UNWILLING_TO_PERFORM;
											goto bail;

										}
									} else {
										/* The config area does not exist */
										PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
											"Unable to locate shared config entry (%s) error %d",
											slapi_sdn_get_dn(memberof_get_config_area()), rc);
										ret = LDAP_UNWILLING_TO_PERFORM;
										goto bail;
									}
								}
							}
							slapi_ch_free_string(&configarea_dn);
							slapi_sdn_free(&config_sdn);
						}
					}
				}
			}
		} else {
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Unable to locate shared config entry (%s)",
				slapi_sdn_get_dn(memberof_get_config_area()));
			ret = LDAP_UNWILLING_TO_PERFORM;
		}
   	}

bail:

	if (ret){
		slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret);
		slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, returntext);
		slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_shared_config_validate - %s/n",
			returntext);
	}
	slapi_sdn_free(&config_sdn);
	if(nextmod)
		slapi_mod_free(&nextmod);
	slapi_mods_free(&smods);
	slapi_entry_free(resulting_e);
	slapi_entry_free(config_entry);
	slapi_ch_free_string(&configarea_dn);

	return ret;
}
示例#3
0
文件: uid.c 项目: ohamada/389ds
/*
 * 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;

}