diff options
-rw-r--r-- | ldap/servers/plugins/replication/repl5_agmt.c | 138 | ||||
-rw-r--r-- | ldap/servers/plugins/usn/usn.c | 40 | ||||
-rw-r--r-- | ldap/servers/plugins/usn/usn.h | 2 | ||||
-rw-r--r-- | ldap/servers/slapd/dse.c | 7 | ||||
-rw-r--r-- | ldap/servers/slapd/plugin.c | 156 | ||||
-rw-r--r-- | ldap/servers/slapd/proto-slap.h | 2 | ||||
-rw-r--r-- | ldap/servers/slapd/slapi-plugin.h | 23 | ||||
-rw-r--r-- | ldap/servers/slapd/slapi-private.h | 2 |
8 files changed, 330 insertions, 40 deletions
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c index 613c222a..dc9b3be2 100644 --- a/ldap/servers/plugins/replication/repl5_agmt.c +++ b/ldap/servers/plugins/replication/repl5_agmt.c @@ -231,6 +231,7 @@ agmt_new_from_entry(Slapi_Entry *e) Repl_Agmt *ra; char *tmpstr; Slapi_Attr *sattr; + char **denied_attrs = NULL; char *auto_initialize = NULL; char *val_nsds5BeginReplicaRefresh = "start"; @@ -396,27 +397,29 @@ agmt_new_from_entry(Slapi_Entry *e) ra->last_init_status[0] = '\0'; /* Fractional attributes */ - if (slapi_entry_attr_find(e, type_nsds5ReplicatedAttributeList, &sattr) == 0) - { - char **denied_attrs = NULL; - /* New set of excluded attributes */ - if (agmt_set_replicated_attributes_from_attr(ra, sattr) != 0) - { - slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_add_callback: " - "failed to parse replicated attributes for agreement %s\n", - agmt_get_long_name(ra)); - } - /* Check that there are no verboten attributes in the exclude list */ - denied_attrs = agmt_validate_replicated_attributes(ra); - if (denied_attrs) - { - /* Report the error to the client */ - slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "WARNING: " - "Attempt to exclude illegal attributes from a fractional agreement\n"); - /* Free the list */ - slapi_ch_array_free(denied_attrs); - goto loser; - } + slapi_entry_attr_find(e, type_nsds5ReplicatedAttributeList, &sattr); + + /* New set of excluded attributes */ + /* Note: even if sattrs is empty, we have to call this func since there + * could be a default excluded attr list in cn=plugin default config */ + if (agmt_set_replicated_attributes_from_attr(ra, sattr) != 0) + { + slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, + "agmtlist_add_callback: failed to parse " + "replicated attributes for agreement %s\n", + agmt_get_long_name(ra)); + } + /* Check that there are no verboten attributes in the exclude list */ + denied_attrs = agmt_validate_replicated_attributes(ra); + if (denied_attrs) + { + /* Report the error to the client */ + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, + "WARNING: Attempt to exclude illegal attributes " + "from a fractional agreement\n"); + /* Free the list */ + slapi_ch_array_free(denied_attrs); + goto loser; } if (!agmt_is_valid(ra)) @@ -488,6 +491,8 @@ agmt_delete(void **rap) slapi_ch_free((void **)&(ra->hostname)); slapi_ch_free((void **)&(ra->binddn)); + slapi_ch_array_free(ra->frac_attrs); + if (NULL != ra->creds) { /* XXX free berval */ @@ -1060,7 +1065,14 @@ agmt_parse_excluded_attrs_next(const char *attr_string, size_t *offset, char*** tmpstr = slapi_ch_malloc(stringlen + 1); strncpy(tmpstr,beginstr,stringlen); tmpstr[stringlen] = '\0'; - charray_add(attrs,tmpstr); + if (charray_inlist(*attrs, tmpstr)) /* tmpstr is already in attrs */ + { + slapi_ch_free_string(&tmpstr); + } + else + { + charray_add(attrs,tmpstr); + } (*offset) += stringlen; /* Skip a delimiting space */ if (c == ' ') @@ -1073,17 +1085,22 @@ agmt_parse_excluded_attrs_next(const char *attr_string, size_t *offset, char*** } return retval; } - /* It looks like this: - nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE jpegPhoto telephoneNumber + +/* It looks like this: + * nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE jpegPhoto telephoneNumber + * This function could be called multiple times: to set excluded attrs in the + * plugin default config and to set the ones in the replica agreement. + * The excluded attrs from replica agreement are added to the ones from + * default config. (Therefore, *attrs should not be initialized in this + * function.) */ static int -agmt_parse_excluded_attrs_config_attr(const char *attr_string, char*** attrs) +agmt_parse_excluded_attrs_config_attr(const char *attr_string, char ***attrs) { int retval = 0; size_t offset = 0; char **new_attrs = NULL; - *attrs = NULL; /* First parse and skip the filter */ retval = agmt_parse_excluded_attrs_filter(attr_string, &offset); if (retval) @@ -1105,13 +1122,78 @@ agmt_parse_excluded_attrs_config_attr(const char *attr_string, char*** attrs) retval = 0; if (new_attrs) { - *attrs = new_attrs; + charray_merge_nodup(attrs, new_attrs, 1); + slapi_ch_array_free(new_attrs); } error: return retval; } /* + * _agmt_set_default_fractional_attrs + * helper function to set nsds5ReplicatedAttributeList value (from cn=plugin + * default config,cn=config) to frac_attrs in Repl_Agmt. + * nsds5ReplicatedAttributeList set in each agreement is added to the + * default list set in this function. + */ +static int +_agmt_set_default_fractional_attrs(Repl_Agmt *ra) +{ + Slapi_PBlock *newpb = NULL; + Slapi_Entry **entries = NULL; + int rc = LDAP_SUCCESS; + char *attrs[2]; + + attrs[0] = (char *)type_nsds5ReplicatedAttributeList; + attrs[1] = NULL; + + newpb = slapi_pblock_new(); + slapi_search_internal_set_pb(newpb, + SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */ + LDAP_SCOPE_BASE, + "(objectclass=*)", + attrs, /* Attrs */ + 0, /* AttrOnly */ + NULL, /* Controls */ + NULL, /* UniqueID */ + repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), + 0); + slapi_search_internal_pb(newpb); + slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + slapi_pblock_get(newpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + ra->frac_attrs = NULL; + if (LDAP_SUCCESS == rc && entries && *entries) /* default config entry exists */ + { + Slapi_Attr *attr; + Slapi_Value *sval = NULL; + if (0 == slapi_entry_attr_find(*entries, + type_nsds5ReplicatedAttributeList, &attr)) + { + int i; + const char *val = NULL; + for (i = slapi_attr_first_value(attr, &sval); + i >= 0; i = slapi_attr_next_value(attr, i, &sval)) { + val = slapi_value_get_string(sval); + rc = agmt_parse_excluded_attrs_config_attr(val, + &(ra->frac_attrs)); + if (0 != rc) { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, + "_agmt_set_default_fractional_attrs: failed to " + "parse default config (%s) attribute value: %s\n", + SLAPI_PLUGIN_DEFAULT_CONFIG, + type_nsds5ReplicatedAttributeList, val); + } + } + } + } + + slapi_free_search_results_internal(newpb); + slapi_pblock_destroy(newpb); + + return rc; +} + +/* * Set or reset the set of replicated attributes. * * Returns 0 if DN set, or -1 if an error occurred. @@ -1130,6 +1212,7 @@ agmt_set_replicated_attributes_from_entry(Repl_Agmt *ra, const Slapi_Entry *e) slapi_ch_array_free(ra->frac_attrs); ra->frac_attrs = NULL; } + _agmt_set_default_fractional_attrs(ra); if (NULL != sattr) { Slapi_Value *sval = NULL; @@ -1162,6 +1245,7 @@ agmt_set_replicated_attributes_from_attr(Repl_Agmt *ra, Slapi_Attr *sattr) slapi_ch_array_free(ra->frac_attrs); ra->frac_attrs = NULL; } + _agmt_set_default_fractional_attrs(ra); if (NULL != sattr) { Slapi_Value *sval = NULL; diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c index 7f464362..fd8f7c58 100644 --- a/ldap/servers/plugins/usn/usn.c +++ b/ldap/servers/plugins/usn/usn.c @@ -112,13 +112,13 @@ usn_init(Slapi_PBlock *pb) rc = slapi_register_plugin("preoperation", 1 /* Enabled */, "usn_preop_init", usn_preop_init, "USN preoperation plugin", NULL, identity); - rc = slapi_register_plugin("bepreoperation", 1 /* Enabled */, + rc |= slapi_register_plugin("bepreoperation", 1 /* Enabled */, "usn_bepreop_init", usn_bepreop_init, "USN bepreoperation plugin", NULL, identity); - rc = slapi_register_plugin("bepostoperation", 1 /* Enabled */, + rc |= slapi_register_plugin("bepostoperation", 1 /* Enabled */, "usn_bepostop_init", usn_bepostop_init, "USN bepostoperation plugin", NULL, identity); - usn_set_identity(identity); + usn_set_identity(identity); bail: slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<-- usn_init\n"); @@ -212,14 +212,40 @@ 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); - - slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<-- usn_start\n"); - + 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); +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_start (rc: %d)\n", rc); return rc; } @@ -547,7 +573,7 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, continue; } /* get a next USN counter from be_usn_counter; then minus 1 from it */ - PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRI64 "d", slapi_counter_get_value(be->be_usn_counter)-1); usn_berval.bv_len = strlen(usn_berval.bv_val); diff --git a/ldap/servers/plugins/usn/usn.h b/ldap/servers/plugins/usn/usn.h index cf0cd184..ac9f86b1 100644 --- a/ldap/servers/plugins/usn/usn.h +++ b/ldap/servers/plugins/usn/usn.h @@ -46,7 +46,7 @@ #define USN_LAST_USN "lastusn" #define USN_LAST_USN_ATTR_CORE_LEN 8 /* lastusn; */ -#define USN_COUNTER_BUF_LEN 32 /* enough size for 64 bit inteters */ +#define USN_COUNTER_BUF_LEN 64 /* enough size for 64 bit integers */ /* usn.c */ void usn_set_identity(void *identity); diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c index 4a0312b2..f0d124ce 100644 --- a/ldap/servers/slapd/dse.c +++ b/ldap/servers/slapd/dse.c @@ -2323,15 +2323,14 @@ dse_search_set_release (void **ss) } void -dse_prev_search_results (Slapi_PBlock *pb) +dse_prev_search_results (void *vp) { + Slapi_PBlock *pb = (Slapi_PBlock *)vp; dse_search_set *ss; - slapi_pblock_get( pb, SLAPI_SEARCH_RESULT_SET, &ss ); + slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &ss); if (ss) { dl_get_prev (&ss->dl, &ss->current_entry); } - return; - } static void diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index e5e016d3..75ec4f92 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -2837,3 +2837,159 @@ bail: return rc; } + +/* + * Set given "type: attr" to the plugin default config entry + * (cn=plugin default config,cn=config) unless the same "type: attr" pair + * already exists in the entry. + */ +int +slapi_set_plugin_default_config(const char *type, Slapi_Value *value) +{ + Slapi_PBlock pb; + Slapi_Entry **entries = NULL; + int rc = LDAP_SUCCESS; + char **search_attrs = NULL; /* used by search */ + + if (NULL == type || '\0' == *type || NULL == value ) { /* nothing to do */ + return rc; + } + + charray_add(&search_attrs, slapi_ch_strdup(type)); + + /* cn=plugin default config,cn=config */ + pblock_init(&pb); + slapi_search_internal_set_pb(&pb, + SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */ + LDAP_SCOPE_BASE, + "(objectclass=*)", + search_attrs, /* Attrs */ + 0, /* AttrOnly */ + NULL, /* Controls */ + NULL, /* UniqueID */ + (void *)plugin_get_default_component_id(), + 0); + slapi_search_internal_pb(&pb); + slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + if (LDAP_SUCCESS == rc && entries && *entries) { + /* plugin default config entry exists */ + int exists = 0; + Slapi_Attr *attr = NULL; + rc = slapi_entry_attr_find(*entries, type, &attr); + + if (0 == rc) { /* type exists in the entry */ + if (0 == + slapi_attr_value_find(attr, slapi_value_get_berval(value))) { + /* value exists in the entry; we don't have to do anything. */ + exists = 1; + } + } + slapi_free_search_results_internal(&pb); + pblock_done(&pb); + + if (!exists) { + /* The argument attr is not in the plugin default config. + * Let's add it. */ + Slapi_Mods smods; + Slapi_Value *va[2]; + + va[0] = value; + va[1] = NULL; + slapi_mods_init(&smods, 1); + slapi_mods_add_mod_values(&smods, LDAP_MOD_ADD, type, va); + + pblock_init(&pb); + slapi_modify_internal_set_pb(&pb, SLAPI_PLUGIN_DEFAULT_CONFIG, + slapi_mods_get_ldapmods_byref(&smods), + NULL, NULL, /* UniqueID */ + (void *)plugin_get_default_component_id(), + 0 /* Flags */ ); + slapi_modify_internal_pb(&pb); + slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + slapi_mods_done(&smods); + pblock_done(&pb); + } + } else { /* cn=plugin default config does not exist. Let's add it. */ + Slapi_Mods smods; + Slapi_Value *va[2]; + + slapi_free_search_results_internal(&pb); + pblock_done(&pb); + + va[0] = value; + va[1] = NULL; + slapi_mods_init(&smods, 1); + + slapi_mods_add_string(&smods, LDAP_MOD_ADD, "objectClass", "top"); + slapi_mods_add_string(&smods, LDAP_MOD_ADD, "objectClass", + "extensibleObject"); + slapi_mods_add_mod_values(&smods, LDAP_MOD_ADD, type, va); + + pblock_init(&pb); + slapi_add_internal_set_pb(&pb, SLAPI_PLUGIN_DEFAULT_CONFIG, + slapi_mods_get_ldapmods_byref(&smods), NULL, + (void *)plugin_get_default_component_id(), + 0 /* Flags */ ); + slapi_add_internal_pb(&pb); + slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + slapi_mods_done(&smods); + pblock_done(&pb); + } + charray_free(search_attrs); + + return rc; +} + +/* + * Get attribute values of given type from the plugin default config entry + * (cn=plugin default config,cn=config). + * + * Caller is responsible to free attrs by slapi_valueset_free. + */ +int +slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset) +{ + Slapi_PBlock pb; + Slapi_Entry **entries = NULL; + int rc = LDAP_PARAM_ERROR; + char **search_attrs = NULL; /* used by search */ + + if (NULL == type || '\0' == *type || NULL == valueset) { /* nothing to do */ + return rc; + } + + charray_add(&search_attrs, slapi_ch_strdup(type)); + + /* cn=plugin default config,cn=config */ + pblock_init(&pb); + slapi_search_internal_set_pb(&pb, + SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */ + LDAP_SCOPE_BASE, + "(objectclass=*)", + search_attrs, /* Attrs */ + 0, /* AttrOnly */ + NULL, /* Controls */ + NULL, /* UniqueID */ + (void *)plugin_get_default_component_id(), + 0); + slapi_search_internal_pb(&pb); + slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + if (LDAP_SUCCESS == rc && entries && *entries) { + /* default config entry exists */ + /* retrieve attribute values from the entry */ + Slapi_Attr *attr = NULL; + rc = slapi_entry_attr_find(*entries, type, &attr); + if (0 == rc) { /* type value exists */ + rc = slapi_attr_get_valueset(attr, valueset); + } else { + rc = LDAP_NO_SUCH_ATTRIBUTE; + } + } + slapi_free_search_results_internal(&pb); + pblock_done(&pb); + charray_free(search_attrs); + + return rc; +} diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 9c6c16ef..4b1bbdf7 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -604,7 +604,7 @@ void dse_unset_dont_ever_write_dse_files(void); int dse_next_search_entry (Slapi_PBlock *pb); char *dse_read_next_entry( char *buf, char **lastp ); void dse_search_set_release (void **ss); -void dse_prev_search_results (Slapi_PBlock *pb); +void dse_prev_search_results (void *pb); /* diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index e59df68b..75a2ddc2 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -3637,6 +3637,29 @@ char **slapi_str2charray_ext( char *str, char *brkstr, int allow_dups ); #endif #endif +/** + * Set given "type: value" to the plugin default config entry + * (cn=plugin default config,cn=config) unless the same "type: value" pair + * already exists in the entry. + * + * \param type Attribute type to add to the default config entry + * \param value Attribute value to add to the default config entry + * \return 0 if the operation was successful + * \return non-0 if the operation was not successful + */ +int slapi_set_plugin_default_config(const char *type, Slapi_Value *value); + +/** + * Get attribute values of given type from the plugin default config entry + * (cn=plugin default config,cn=config). + * + * \param type Attribute type to get from the default config entry + * \param valueset Valueset holding the attribute values + * \return 0 if the operation was successful + * \return non-0 if the operation was not successful + * \warning Caller is responsible to free attrs by slapi_ch_array_free + * */ +int slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset); #ifdef __cplusplus } diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h index c09e9759..0f32f004 100644 --- a/ldap/servers/slapd/slapi-private.h +++ b/ldap/servers/slapd/slapi-private.h @@ -1177,6 +1177,8 @@ void bervalarray_add_berval_fast(struct berval ***vals, const struct berval *add configuration entries will be found */ #define PLUGIN_BASE_DN "cn=plugins,cn=config" +#define SLAPI_PLUGIN_DEFAULT_CONFIG "cn=plugin default config,cn=config" + /***** End of items added for the replication plugin. ***********************/ void DS_Sleep(PRIntervalTime ticks); |