示例#1
0
文件: common.c 项目: LiptonB/freeipa
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
                        int *is_root, int *is_krb, int *is_smb, int *is_ipant,
                        char *attr, int acc)
{
    Slapi_Value *sval;
    int rc;

    /* Check ACIs */
    slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, is_root);

    if (!*is_root) {
        /* verify this user is allowed to write a user password */
        rc = slapi_access_allowed(pb, e, attr, NULL, acc);
        if (rc != LDAP_SUCCESS) {
            /* we have no business here, the operation will be denied anyway */
            rc = LDAP_SUCCESS;
            goto done;
        }
    }

    /* Check if this is a krbPrincial and therefore needs us to generate other
     * hashes */
    sval = slapi_value_new_string("krbPrincipalAux");
    if (!sval) {
        rc = LDAP_OPERATIONS_ERROR;
        goto done;
    }
    *is_krb = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sval);
    slapi_value_free(&sval);

    sval = slapi_value_new_string("sambaSamAccount");
    if (!sval) {
        rc = LDAP_OPERATIONS_ERROR;
        goto done;
    }
    *is_smb = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sval);
    slapi_value_free(&sval);

    sval = slapi_value_new_string("ipaNTUserAttrs");
    if (!sval) {
        rc = LDAP_OPERATIONS_ERROR;
        goto done;
    }
    *is_ipant = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
                                                  sval);
    slapi_value_free(&sval);

    rc = LDAP_SUCCESS;

done:
    return rc;
}
示例#2
0
文件: usn.c 项目: leto/389-ds
/*
 * usn_start: usn_rootdse_init -- set rootdse callback to aggregate in rootDSE
 *            usn_cleanup_start -- initialize USN tombstone cleanup task
 */
static int
usn_start(Slapi_PBlock *pb)
{
    int rc = 0;
    Slapi_Value *value;

    slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> usn_start\n");

    rc = usn_rootdse_init();
    rc |= usn_cleanup_start(pb);
    if (rc) {
        goto bail;
    }
    if (0) { /* Not executed; test code for slapi_get_plugin_default_config */
        Slapi_ValueSet *vs = NULL;
        Slapi_Value *v = NULL;
        int i;

        slapi_get_plugin_default_config("nsds5ReplicatedAttributeList", &vs);
        if (vs) {
            for (i = slapi_valueset_first_value(vs, &v);
                 i != -1;
                 i = slapi_valueset_next_value(vs, i, &v)) {
                slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
                        "nsds5ReplicatedAttributeList: %s\n", 
                        slapi_value_get_string(v));
            }
        }
        slapi_valueset_free(vs);
    }
    /* add nsds5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE entryusn 
     * to cn=plugin default config,cn=config */
    value = slapi_value_new_string("(objectclass=*) $ EXCLUDE entryusn");
    rc = slapi_set_plugin_default_config("nsds5ReplicatedAttributeList", value);
    slapi_value_free(&value);
    g_plugin_started = 1;
bail:
    slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
                    "<-- usn_start (rc: %d)\n", rc);
    return rc;
}
示例#3
0
文件: common.c 项目: LiptonB/freeipa
/* Modify the Password attributes of the entry */
int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
                       struct ipapwd_data *data, int is_krb)
{
    int ret = 0;
    Slapi_Mods *smods = NULL;
    Slapi_Value **svals = NULL;
    Slapi_Value **ntvals = NULL;
    Slapi_Value **pwvals = NULL;
    char *nt = NULL;
    int is_smb = 0;
    int is_ipant = 0;
    int is_host = 0;
    Slapi_Value *sambaSamAccount;
    Slapi_Value *ipaNTUserAttrs;
    Slapi_Value *ipaHost;
    char *errMesg = NULL;
    char *modtime = NULL;

    LOG_TRACE("=>\n");

    sambaSamAccount = slapi_value_new_string("sambaSamAccount");
    if (slapi_entry_attr_has_syntax_value(data->target,
                                          "objectClass", sambaSamAccount)) {
        is_smb = 1;
    }
    slapi_value_free(&sambaSamAccount);

    ipaNTUserAttrs = slapi_value_new_string("ipaNTUserAttrs");
    if (slapi_entry_attr_has_syntax_value(data->target,
                                          "objectClass", ipaNTUserAttrs)) {
        is_ipant = 1;
    }
    slapi_value_free(&ipaNTUserAttrs);

    ipaHost = slapi_value_new_string("ipaHost");
    if (slapi_entry_attr_has_syntax_value(data->target,
                                          "objectClass", ipaHost)) {
        is_host = 1;
    }
    slapi_value_free(&ipaHost);

    ret = ipapwd_gen_hashes(krbcfg, data,
                            data->password,
                            is_krb, is_smb, is_ipant,
                            &svals, &nt, &ntvals, &errMesg);
    if (ret) {
        goto free_and_return;
    }

    smods = slapi_mods_new();

    if (svals) {
        slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
                                  "krbPrincipalKey", svals);

		/* krbLastPwdChange is used to tell whether a host entry has a
		 * keytab so don't set it on hosts.
		 */
        if (!is_host) {
	    /* change Last Password Change field with the current date */
            ret = ipapwd_setdate(data->target, smods, "krbLastPwdChange",
                                 data->timeNow, false);
            if (ret != LDAP_SUCCESS)
                goto free_and_return;

	    /* set Password Expiration date */
            ret = ipapwd_setdate(data->target, smods, "krbPasswordExpiration",
                                 data->expireTime, (data->expireTime == 0));
            if (ret != LDAP_SUCCESS)
                goto free_and_return;
	}
    }

    if (nt && is_smb) {
        slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                              "sambaNTPassword", nt);
    }

    if (ntvals && is_ipant) {
        slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
                                  "ipaNTHash", ntvals);
    }

    if (is_smb) {
        /* with samba integration we need to also set sambaPwdLastSet or
         * samba will decide the user has to change the password again */
        if (data->changetype == IPA_CHANGETYPE_ADMIN) {
            /* if it is an admin change instead we need to let know to
             * samba as well that the use rmust change its password */
            modtime = slapi_ch_smprintf("0");
        } else {
            modtime = slapi_ch_smprintf("%ld", (long)data->timeNow);
        }
        if (!modtime) {
            LOG_FATAL("failed to smprintf string!\n");
            ret = LDAP_OPERATIONS_ERROR;
            goto free_and_return;
        }
        slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                              "sambaPwdLastset", modtime);
    }
    if (is_krb) {
        if (data->changetype == IPA_CHANGETYPE_ADMIN) {
            slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                                 "krbLoginFailedCount", "0");
        }
    }
    /* let DS encode the password itself, this allows also other plugins to
     * intercept it to perform operations like synchronization with Active
     * Directory domains through the replication plugin */
    slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                          "userPassword", data->password);

    /* set password history */
    if (data->policy.history_length > 0) {
        pwvals = ipapwd_setPasswordHistory(smods, data);
        if (pwvals) {
            slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
                                      "passwordHistory", pwvals);
        }
    }

    /* FIXME:
     * instead of replace we should use a delete/add so that we are
     * completely sure nobody else modified the entry meanwhile and
     * fail if that's the case */

    /* commit changes */
    ret = ipapwd_apply_mods(data->dn, smods);

    LOG_TRACE("<= result: %d\n", ret);

free_and_return:
    if (nt) slapi_ch_free((void **)&nt);
    if (modtime) slapi_ch_free((void **)&modtime);
    slapi_mods_free(&smods);
    ipapwd_free_slapi_value_array(&svals);
    ipapwd_free_slapi_value_array(&ntvals);
    ipapwd_free_slapi_value_array(&pwvals);

    return ret;
}
示例#4
0
static int
ipa_winsync_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore,
                          Slapi_Entry* e, int *returncode, char *returntext,
                          void *arg)
{
    PRBool flatten = PR_TRUE;
    char *realm_filter = NULL;
    char *realm_attr = NULL;
    char *new_entry_filter = NULL;
    char *new_user_oc_attr = NULL; /* don't care about groups for now */
    char *homedir_prefix_attr = NULL;
    char *login_shell_attr = NULL;
    char *default_group_attr = NULL;
    char *default_group_filter = NULL;
    char *acct_disable = NULL;
    int acct_disable_int;
    char *inactivated_filter = NULL;
    char *activated_filter = NULL;
    char **attrsvals = NULL;
    int ii;
    Slapi_Attr *testattr = NULL;
    PRBool forceSync = PR_FALSE;

    *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */

    /* get flatten value */
    if (!slapi_entry_attr_find(e, IPA_WINSYNC_USER_FLATTEN, &testattr) &&
        (NULL != testattr)) {
        flatten = slapi_entry_attr_get_bool(e, IPA_WINSYNC_USER_FLATTEN);
    }

    /* get realm filter */
    if (!(realm_filter = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_REALM_FILTER_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_REALM_FILTER_ATTR);
        goto done3;
    }

    /* get realm attr */
    if (!(realm_attr = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_REALM_ATTR_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_REALM_ATTR_ATTR);
        goto done3;
    }

    /* get new_entry_filter */
    if (!(new_entry_filter = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_NEW_ENTRY_FILTER_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_NEW_ENTRY_FILTER_ATTR);
        goto done3;
    }

    /* get new_user_oc_attr */
    if (!(new_user_oc_attr = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_NEW_USER_OC_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_NEW_USER_OC_ATTR);
        goto done3;
    }

    /* get homedir_prefix_attr */
    if (!(homedir_prefix_attr = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_HOMEDIR_PREFIX_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_HOMEDIR_PREFIX_ATTR);
        goto done3;
    }

    /* get login_shell_attr */
    login_shell_attr = slapi_entry_attr_get_charptr(e,
                                                IPA_WINSYNC_LOGIN_SHELL_ATTR);
    if (!login_shell_attr) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Warning: no value given for %s",
                    IPA_WINSYNC_LOGIN_SHELL_ATTR);
    }

    /* get default_group_attr */
    if (!(default_group_attr = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_DEFAULTGROUP_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_DEFAULTGROUP_ATTR);
        goto done3;
    }

    /* get default_group_filter */
    if (!(default_group_filter = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_DEFAULTGROUP_FILTER_ATTR))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_DEFAULTGROUP_FILTER_ATTR);
        goto done3;
    }

    /* get the list of attributes & values */
    /* get new_user_oc_attr */
    if (!(attrsvals = slapi_entry_attr_get_charray(
              e, IPA_WINSYNC_NEW_USER_ATTRS_VALS))) {
        LOG("Info: no default attributes and values given in [%s]\n",
            IPA_WINSYNC_NEW_USER_ATTRS_VALS);
    }

    /* get acct disable sync value */
    if (!(acct_disable = slapi_entry_attr_get_charptr(
              e, IPA_WINSYNC_ACCT_DISABLE))) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: no value given for %s",
                    IPA_WINSYNC_ACCT_DISABLE);
        goto done3;
    }

    acct_disable_int = parse_acct_disable(acct_disable);
    if (ACCT_DISABLE_INVALID == acct_disable_int) {
        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                    "Error: invalid value [%s] given for [%s] - valid "
                    "values are " IPA_WINSYNC_ACCT_DISABLE_NONE
                    ", " IPA_WINSYNC_ACCT_DISABLE_TO_AD
                    ", " IPA_WINSYNC_ACCT_DISABLE_TO_DS
                    ", or " IPA_WINSYNC_ACCT_DISABLE_BOTH,
                    acct_disable, IPA_WINSYNC_ACCT_DISABLE);
        goto done3;
    }

    if (acct_disable_int != ACCT_DISABLE_NONE) {
        /* get inactivated group filter */
        if (!(inactivated_filter = slapi_entry_attr_get_charptr(
                  e, IPA_WINSYNC_INACTIVATED_FILTER))) {
            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                        "No value given for %s - required for account "
                        "disable sync, ignoring",
                        IPA_WINSYNC_INACTIVATED_FILTER);
        }
        /* get activated group filter */
        if (!(activated_filter = slapi_entry_attr_get_charptr(
                  e, IPA_WINSYNC_ACTIVATED_FILTER))) {
            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                        "No value given for %s - required for account "
                        "disable sync, ignoring",
                        IPA_WINSYNC_ACTIVATED_FILTER);
        }
    }

    /* get forceSync value */
    if (!slapi_entry_attr_find(e, IPA_WINSYNC_FORCE_SYNC, &testattr) &&
        (NULL != testattr)) {
        forceSync = slapi_entry_attr_get_bool(e, IPA_WINSYNC_FORCE_SYNC);
    }

    /* if we got here, we have valid values for everything
       set the config entry */
    slapi_lock_mutex(theConfig.lock);
    slapi_entry_free(theConfig.config_e);
    theConfig.config_e = slapi_entry_alloc();
    slapi_entry_init(theConfig.config_e, slapi_ch_strdup(""), NULL);

    /* format of *attrsvals is "attrname value" */
    /* attrname <space> value */
    /* value may contain spaces - attrname is everything up to the first
       space - value is everything after the first space */
    for (ii = 0; attrsvals && attrsvals[ii]; ++ii) {
        int rc;
        Slapi_Value *sva[2];
        Slapi_Value *sv = NULL;
        char *val = strchr(attrsvals[ii], ' ');
        if (!val || !*(val+1)) { /* incorrect format or no value */
            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                        "Error: no value or incorrect value given for [%s] "
                        "value [%s] index [%d] - correct format is attrname SPACE value",
                        IPA_WINSYNC_NEW_USER_ATTRS_VALS,
                        attrsvals[ii], ii);
            goto done3;
        }
        *val++ = '\0'; /* separate attr from val */
        sv = slapi_value_new_string(val);
        sva[0] = sv;
        sva[1] = NULL;
        if ((rc = slapi_entry_add_values_sv(theConfig.config_e,
                                            attrsvals[ii], sva)) &&
            (rc != LDAP_SUCCESS)) {
            PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
                        "Error: could not add value [%s] for attribute name "
                        "[%s] - ldap error [%d: %s]", val, attrsvals[ii],
                        rc, ldap_err2string(rc));
            slapi_entry_free(theConfig.config_e);
            theConfig.config_e = NULL;
            slapi_value_free(&sv);
            goto done3;
        }
        slapi_value_free(&sv);
    }

    /* all of the attrs and vals have been set - set the other values */
    slapi_ch_free_string(&theConfig.realm_filter);
    theConfig.realm_filter = realm_filter;
    realm_filter = NULL;
    slapi_ch_free_string(&theConfig.realm_attr);
    theConfig.realm_attr = realm_attr;
    realm_attr = NULL;
    slapi_ch_free_string(&theConfig.new_entry_filter);
    theConfig.new_entry_filter = new_entry_filter;
    new_entry_filter = NULL;
    slapi_ch_free_string(&theConfig.new_user_oc_attr);
    theConfig.new_user_oc_attr = new_user_oc_attr;
    new_user_oc_attr = NULL;
    slapi_ch_free_string(&theConfig.homedir_prefix_attr);
    theConfig.homedir_prefix_attr = homedir_prefix_attr;
    homedir_prefix_attr = NULL;
    if (login_shell_attr) {
        slapi_ch_free_string(&theConfig.login_shell_attr);
        theConfig.login_shell_attr = login_shell_attr;
        login_shell_attr = NULL;
    }
    slapi_ch_free_string(&theConfig.default_group_attr);
    theConfig.default_group_attr = default_group_attr;
    default_group_attr = NULL;
    slapi_ch_free_string(&theConfig.default_group_filter);
    theConfig.default_group_filter = default_group_filter;
    default_group_filter = NULL;
    theConfig.flatten = flatten;
    theConfig.acct_disable = parse_acct_disable(acct_disable);
    slapi_ch_free_string(&theConfig.inactivated_filter);
    theConfig.inactivated_filter = inactivated_filter;
    inactivated_filter = NULL;
    slapi_ch_free_string(&theConfig.activated_filter);
    theConfig.activated_filter = activated_filter;
    activated_filter = NULL;
    theConfig.forceSync = forceSync;

    /* success */
    *returncode = LDAP_SUCCESS;

done3:
    slapi_unlock_mutex(theConfig.lock);

    slapi_ch_free_string(&realm_filter);
    slapi_ch_free_string(&realm_attr);
    slapi_ch_free_string(&new_entry_filter);
    slapi_ch_free_string(&new_user_oc_attr);
    slapi_ch_free_string(&homedir_prefix_attr);
    slapi_ch_free_string(&login_shell_attr);
    slapi_ch_free_string(&default_group_attr);
    slapi_ch_free_string(&default_group_filter);
    slapi_ch_array_free(attrsvals);
    attrsvals = NULL;
    slapi_ch_free_string(&acct_disable);
    slapi_ch_free_string(&inactivated_filter);
    slapi_ch_free_string(&activated_filter);

    if (*returncode != LDAP_SUCCESS) {
        return SLAPI_DSE_CALLBACK_ERROR;
    } else {
        return SLAPI_DSE_CALLBACK_OK;
    }
}
示例#5
0
文件: uid.c 项目: ohamada/389ds
/*
 * preop_modrdn - Pre-operation call for modify RDN
 *
 * Check that the new RDN does not include attributes that
 * cause a constraint violation
 */
static int
preop_modrdn(Slapi_PBlock *pb)
{
  int result = LDAP_SUCCESS;
  Slapi_Entry *e = NULL;
  Slapi_Value *sv_requiredObjectClass = NULL;
  char *errtext = NULL;
  char *attrName = NULL;

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

  BEGIN
    int err;
    char *markerObjectClass=NULL;
    char *requiredObjectClass=NULL;
    Slapi_DN *sdn = NULL;
    Slapi_DN *superior;
    char *rdn;
    int deloldrdn = 0;
    int isupdatedn;
    Slapi_Attr *attr;
    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(30); 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;
        }

    /* Create a Slapi_Value for the requiredObjectClass to use
     * for checking the entry. */
    if (requiredObjectClass) {
        sv_requiredObjectClass = slapi_value_new_string(requiredObjectClass);
    }

    /* Get the DN of the entry being renamed */
    err = slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sdn);
    if (err) { result = uid_op_error(31); break; }

    /* Get superior value - unimplemented in 3.0/4.0/5.0 DS */
    err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &superior);
    if (err) { result = uid_op_error(32); break; }

    /*
     * No superior means the entry is just renamed at
     * its current level in the tree.  Use the target DN for
     * determining which managed tree this belongs to
     */
    if (!superior) superior = sdn;

    /* Get the new RDN - this has the attribute values */
    err = slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &rdn);
    if (err) { result = uid_op_error(33); break; }
#ifdef DEBUG
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
      "MODRDN newrdn=%s\n", rdn);
#endif

    /* See if the old RDN value is being deleted. */
    err = slapi_pblock_get(pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn);
    if (err) { result = uid_op_error(34); break; }

    /* Get the entry that is being renamed so we can make a dummy copy
     * of what it will look like after the rename. */
    err = slapi_search_internal_get_entry(sdn, NULL, &e, plugin_identity);
    if (err != LDAP_SUCCESS) {
        result = uid_op_error(35);
        /* We want to return a no such object error if the target doesn't exist. */
        if (err == LDAP_NO_SUCH_OBJECT) {
            result = err;
        }
        break;
    }

    /* Apply the rename operation to the dummy entry. */
    /* slapi_entry_rename does not expect rdn normalized */
    err = slapi_entry_rename(e, rdn, deloldrdn, superior);
    if (err != LDAP_SUCCESS) { result = uid_op_error(36); break; }

        /*
         * Find any unique attribute data in the new RDN
         */
        err = slapi_entry_attr_find(e, attrName, &attr);
        if (err) break;  /* no UID attribute */

        /*
         * Check if it has the required object class
         */
        if (requiredObjectClass &&
            !slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sv_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.
         */
        if (NULL != markerObjectClass)
        {
          /* Subtree defined by location of marker object class */
                result = findSubtreeAndSearch(slapi_entry_get_sdn(e), attrName, attr, NULL,
                                              requiredObjectClass, sdn,
                                              markerObjectClass);
        } else
        {
          /* Subtrees listed on invocation line */
          result = searchAllSubtrees(argc, argv, attrName, attr, NULL,
                                     requiredObjectClass, sdn);
        }
  END
  /* Clean-up */
  slapi_value_free(&sv_requiredObjectClass);
  if (e) slapi_entry_free(e);

  if (result)
  {
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
      "MODRDN 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;

}
示例#6
0
/**
   Apply the mods to the ec entry.  Check for syntax, schema problems.
   Check for abandon.

   Return code:
   -1 - error - result code and message are set appropriately
   0 - successfully applied and checked
   1 - not an error - no mods to apply or op abandoned
 */
static int
modify_apply_check_expand(
	Slapi_PBlock *pb,
	Slapi_Operation *operation,
	LDAPMod **mods, /* list of mods to apply */
	struct backentry *e, /* original "before" entry */
	struct backentry *ec, /* "after" entry with mods applied */
	Slapi_Entry **postentry,
	int *ldap_result_code,
	char **ldap_result_message
)
{
	int rc = 0;
	int i;
	int repl_op;
	int change_entry = 0;
	Slapi_Mods smods = {0};
	CSN *csn = operation_get_csn(operation);

	slapi_pblock_get (pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op);
	slapi_mods_init_byref( &smods, mods );

	if ( (change_entry = mods_have_effect (ec->ep_entry, &smods)) ) {
		*ldap_result_code = entry_apply_mods_wsi(ec->ep_entry, &smods, csn,
												 operation_is_flag_set(operation, OP_FLAG_REPLICATED));
		/*
		 * XXXmcs: it would be nice to get back an error message from
		 * the above call so we could pass it along to the client, e.g.,
		 * "duplicate value for attribute givenName."
		 */
	} else {
		Slapi_Entry *epostop = NULL;
		/* If the entry was not actually changed, we still need to
		 * set the SLAPI_ENTRY_POST_OP field in the pblock (post-op
		 * plugins expect that field to be present for all modify
		 * operations that return LDAP_SUCCESS).
		 */
		slapi_pblock_get ( pb, SLAPI_ENTRY_POST_OP, &epostop );
		slapi_entry_free ( epostop ); /* free existing one, if any */
		slapi_pblock_set ( pb, SLAPI_ENTRY_POST_OP, slapi_entry_dup( e->ep_entry ) );
		*postentry = NULL; /* to avoid free in main error cleanup code */
	}
	if ( !change_entry || *ldap_result_code != 0 ) {
		/* change_entry == 0 is not an error just a no-op */
		rc = change_entry ? -1 : 1;
		goto done;
	}

	/*
	 * If the objectClass attribute type was modified in any way, expand
	 * the objectClass values to reflect the inheritance hierarchy.
	 */
	for ( i = 0; mods && mods[i]; ++i ) {
		if ( 0 == strcasecmp( SLAPI_ATTR_OBJECTCLASS, mods[i]->mod_type )) {
			slapi_schema_expand_objectclasses( ec->ep_entry );
			break;
		}
	}

	/*
	 * We are about to pass the last abandon test, so from now on we are
	 * committed to finish this operation. Set status to "will complete"
	 * before we make our last abandon check to avoid race conditions in
	 * the code that processes abandon operations.
	 */
	operation->o_status = SLAPI_OP_STATUS_WILL_COMPLETE;
	if ( slapi_op_abandoned( pb ) ) {
		rc = 1;
		goto done;
	}

	/* multimaster replication can result in a schema violation,
	 * although the individual operations on each master were valid
	 * It is too late to resolve this. But we can check schema and
	 * add a replication conflict attribute.
	 */
	/* check that the entry still obeys the schema */
	if ((operation_is_flag_set(operation,OP_FLAG_ACTION_SCHEMA_CHECK)) &&
			slapi_entry_schema_check_ext( pb, ec->ep_entry, 1 ) != 0 ) {
		if(repl_op){
			Slapi_Attr *attr;
			Slapi_Mods smods;
			LDAPMod **lmods;
			if (slapi_entry_attr_find (ec->ep_entry, ATTR_NSDS5_REPLCONFLICT, &attr) == 0)
			{
				/* add value */ 
				Slapi_Value *val = slapi_value_new_string("Schema violation");
				slapi_attr_add_value(attr,val);
				slapi_value_free(&val);
			} else {
				/* Add new attribute */
				slapi_entry_add_string (ec->ep_entry, ATTR_NSDS5_REPLCONFLICT, "Schema violation");
			}
			/* the replconflict attribute is indexed and the index is built from the mods,
			 * so we need to extend the mods */
			slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &lmods);
			slapi_mods_init_passin(&smods, lmods);
			slapi_mods_add_string (&smods, LDAP_MOD_ADD, ATTR_NSDS5_REPLCONFLICT, "Schema violation");
			lmods = slapi_mods_get_ldapmods_passout(&smods);
			slapi_pblock_set(pb, SLAPI_MODIFY_MODS, lmods);
			slapi_mods_done(&smods);
			
		} else {
			*ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, ldap_result_message);
			rc = -1;
			goto done;
		}
	}

	if(!repl_op){
		/* check attribute syntax for the new values */
		if (slapi_mods_syntax_check(pb, mods, 0) != 0) {
			*ldap_result_code = LDAP_INVALID_SYNTAX;
			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, ldap_result_message);
			rc = -1;
			goto done;
		}

		/*
		 * make sure the entry contains all values in the RDN.
		 * if not, the modification must have removed them.
		 */
		if ( ! slapi_entry_rdn_values_present( ec->ep_entry ) ) {
			*ldap_result_code= LDAP_NOT_ALLOWED_ON_RDN;
			rc = -1;
			goto done;
		}
	}

done:
	slapi_mods_done( &smods );

	return rc;
}