void retrocl_create_cle (void) { Slapi_PBlock *pb = NULL; Slapi_Entry *e; int rc; struct berval *vals[2]; struct berval val; vals[0] = &val; vals[1] = NULL; e = slapi_entry_alloc(); slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_CHANGELOG_DN)); /* Set the objectclass attribute */ val.bv_val = "top"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "nsContainer"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "changelog"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "cn", vals ); val.bv_val = RETROCL_ACL; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "aci", vals ); pb = slapi_pblock_new (); slapi_add_entry_internal_set_pb( pb, e, NULL /* controls */, g_plg_identity[PLUGIN_RETROCL], 0 /* actions */ ); slapi_add_internal_pb (pb); slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_RESULT, &rc ); slapi_pblock_destroy(pb); if (rc == 0) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "created cn=changelog\n"); } else if (rc == LDAP_ALREADY_EXISTS) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "cn=changelog already existed\n"); } else { slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "cn=changelog could not be created (%d)\n", rc); } }
/* * Read configuration and create a configuration data structure. * This is called after the server has configured itself so we can check * schema and whatnot. * Returns an LDAP error code (LDAP_SUCCESS if all goes well). */ int ipa_winsync_config(Slapi_Entry *config_e) { int returncode = LDAP_SUCCESS; char returntext[SLAPI_DSE_RETURNTEXT_SIZE]; if ( inited ) { LOG_FATAL("Error: IPA WinSync plug-in already configured. " "Please remove the plugin config entry [%s]\n", slapi_entry_get_dn_const(config_e)); return( LDAP_PARAM_ERROR ); } /* initialize fields */ if ((theConfig.lock = slapi_new_mutex()) == NULL) { return( LDAP_LOCAL_ERROR ); } /* init defaults */ theConfig.config_e = slapi_entry_alloc(); slapi_entry_init(theConfig.config_e, slapi_ch_strdup(""), NULL); theConfig.flatten = PR_TRUE; if (SLAPI_DSE_CALLBACK_OK == ipa_winsync_validate_config(NULL, NULL, config_e, &returncode, returntext, NULL)) { ipa_winsync_apply_config(NULL, NULL, config_e, &returncode, returntext, NULL); } /* config DSE must be initialized before we get here */ if (returncode == LDAP_SUCCESS) { const char *config_dn = slapi_entry_get_dn_const(config_e); slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE, IPA_WINSYNC_CONFIG_FILTER, ipa_winsync_validate_config,NULL); slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_POSTOP, config_dn, LDAP_SCOPE_BASE, IPA_WINSYNC_CONFIG_FILTER, ipa_winsync_apply_config,NULL); slapi_config_register_callback(SLAPI_OPERATION_MODRDN, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE, IPA_WINSYNC_CONFIG_FILTER, dont_allow_that, NULL); slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE, IPA_WINSYNC_CONFIG_FILTER, dont_allow_that, NULL); slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, config_dn, LDAP_SCOPE_BASE, IPA_WINSYNC_CONFIG_FILTER, ipa_winsync_search,NULL); } inited = 1; if (returncode != LDAP_SUCCESS) { LOG_FATAL("Error %d: %s\n", returncode, returntext); } return returncode; }
Slapi_Entry * sync_deleted_entry_from_changelog(Slapi_Entry *cl_entry) { Slapi_Entry *db_entry = NULL; char *entrydn = NULL; char *uniqueid = NULL; entrydn = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_ENTRYDN); uniqueid = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_UNIQUEID); /* when the Retro CL can provide the deleted entry * the entry will be taken from th RCL. * For now. just create an entry to holde the nsuniqueid */ db_entry = slapi_entry_alloc(); slapi_entry_init(db_entry, entrydn, NULL); slapi_entry_add_string(db_entry, "nsuniqueid", uniqueid); slapi_ch_free((void**)&uniqueid); return(db_entry); }
/* * Take a bunch of strings, and create a index config entry */ Slapi_Entry * ldbm_instance_init_config_entry(char *cn_val, char *val1, char *val2, char *val3, char *val4){ Slapi_Entry *e = slapi_entry_alloc(); struct berval *vals[2]; struct berval val; vals[0] = &val; vals[1] = NULL; slapi_entry_set_dn(e,slapi_ch_strdup("cn=indexContainer")); val.bv_val = cn_val; val.bv_len = strlen(cn_val); slapi_entry_add_values(e,"cn",vals); val.bv_val = val1; val.bv_len = strlen(val1); slapi_entry_add_values(e,"nsIndexType",vals); if(val2){ val.bv_val = val2; val.bv_len = strlen(val2); slapi_entry_add_values(e,"nsIndexType",vals); } if(val3){ val.bv_val = val3; val.bv_len = strlen(val3); slapi_entry_add_values(e,"nsIndexType",vals); } if(val4){ val.bv_val = val4; val.bv_len = strlen(val4); slapi_entry_add_values(e,"nsIndexType",vals); } return e; }
/* This function is called to process operation that come over external connections */ void do_add( Slapi_PBlock *pb ) { Slapi_Operation *operation; BerElement *ber; char *last; ber_len_t len = LBER_ERROR; ber_tag_t tag; Slapi_Entry *e = NULL; int err; int rc; PRBool searchsubentry=PR_TRUE; slapi_log_err(SLAPI_LOG_TRACE, "do_add", "==>\n"); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); ber = operation->o_ber; /* count the add request */ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps); /* * Parse the add request. It looks like this: * * AddRequest := [APPLICATION 14] SEQUENCE { * name DistinguishedName, * attrs SEQUENCE OF SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } */ /* get the name */ { char *rawdn = NULL; Slapi_DN mysdn; if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) { slapi_ch_free_string(&rawdn); slapi_log_err(SLAPI_LOG_ERR, "do_add", "ber_scanf failed (op=Add; params=DN)\n"); op_shared_log_error_access (pb, "ADD", "???", "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); return; } /* Check if we should be performing strict validation. */ if (config_get_dn_validate_strict()) { /* check that the dn is formatted correctly */ rc = slapi_dn_syntax_check(pb, rawdn, 1); if (rc) { /* syntax check failed */ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"", "strict: invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_ch_free_string(&rawdn); return; } } slapi_sdn_init_dn_passin(&mysdn, rawdn); if (rawdn && (strlen(rawdn) > 0) && (NULL == slapi_sdn_get_dn(&mysdn))) { /* normalization failed */ op_shared_log_error_access(pb, "ADD", rawdn, "invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_sdn_done(&mysdn); return; } e = slapi_entry_alloc(); /* Responsibility for DN is passed to the Entry. */ slapi_entry_init_ext(e, &mysdn, NULL); slapi_sdn_done(&mysdn); } slapi_log_err(SLAPI_LOG_ARGS, "do_add", "dn (%s)\n", (char *)slapi_entry_get_dn_const(e)); /* get the attrs */ for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET; tag = ber_next_element( ber, &len, last ) ) { char *type = NULL, *normtype = NULL; struct berval **vals = NULL; len = -1; /* reset - not used in loop */ if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); slapi_ch_free_string(&type); ber_bvecfree( vals ); goto free_and_return; } if ( vals == NULL ) { slapi_log_err(SLAPI_LOG_ERR, "do_add - no values for type %s\n", type, 0, 0 ); op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "null value"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL ); slapi_ch_free_string(&type); goto free_and_return; } normtype = slapi_attr_syntax_normalize(type); if ( !normtype || !*normtype ) { char ebuf[SLAPI_DSE_RETURNTEXT_SIZE]; rc = LDAP_INVALID_SYNTAX; slapi_create_errormsg(ebuf, sizeof(ebuf), "invalid type '%s'", type); op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), ebuf); send_ldap_result( pb, rc, NULL, ebuf, 0, NULL ); slapi_ch_free_string(&type); slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); goto free_and_return; } slapi_ch_free_string(&type); /* for now we just ignore attributes that client is not allowed to modify so not to break existing clients */ if (op_shared_is_allowed_attr (normtype, pb->pb_conn->c_isreplication_session)){ if (( rc = slapi_entry_add_values( e, normtype, vals )) != LDAP_SUCCESS ) { slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n", pb->pb_conn->c_connid, operation->o_opid, slapi_entry_get_dn_const(e), normtype ); send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); goto free_and_return; } /* if this is uniqueid attribute, set uniqueid field of the entry */ if (strcasecmp (normtype, SLAPI_ATTR_UNIQUEID) == 0) { e->e_uniqueid = slapi_ch_strdup (vals[0]->bv_val); } if(searchsubentry) searchsubentry=check_oc_subentry(e,vals,normtype); } slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); } /* Ensure that created attributes are not used in the RDN. */ if (check_rdn_for_created_attrs(e)) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)), "invalid DN"); send_ldap_result( pb, LDAP_INVALID_DN_SYNTAX, NULL, "illegal attribute in RDN", 0, NULL ); goto free_and_return; } /* len, is ber_len_t, which is uint. Can't be -1. May be better to remove (len != 0) check */ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); goto free_and_return; } /* * in LDAPv3 there can be optional control extensions on * the end of an LDAPMessage. we need to read them in and * pass them to the backend. */ if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "failed to decode LDAP controls"); send_ldap_result( pb, err, NULL, NULL, 0, NULL ); goto free_and_return; } slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot ); slapi_pblock_set( pb, SLAPI_ADD_ENTRY, e ); if (pb->pb_conn->c_flags & CONN_FLAG_IMPORT) { /* this add is actually part of a bulk import -- punt */ handle_fast_add(pb, e); } else { op_shared_add ( pb ); } /* make sure that we don't free entry if it is successfully added */ e = NULL; free_and_return:; if (e) slapi_entry_free (e); }
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; } }
static int retrocl_create_be(const char *bedir) { Slapi_PBlock *pb = NULL; Slapi_Entry *e; struct berval *vals[2]; struct berval val; int rc; vals[0] = &val; vals[1] = NULL; e = slapi_entry_alloc(); /* RETROCL_LDBM_DN is no need to be normalized. */ slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_LDBM_DN)); /* Set the objectclass attribute */ val.bv_val = "top"; val.bv_len = 3; slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "extensibleObject"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "nsBackendInstance"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); val.bv_val = "changelog"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "cn", vals ); val.bv_val = RETROCL_BE_CACHESIZE; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-cachesize", vals ); val.bv_val = RETROCL_CHANGELOG_DN; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-suffix", vals ); val.bv_val = RETROCL_BE_CACHEMEMSIZE; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-cachememsize", vals ); val.bv_val = "off"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-readonly", vals ); if (bedir) { val.bv_val = (char *)bedir; /* cast const */ val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-directory", vals ); } pb = slapi_pblock_new (); slapi_add_entry_internal_set_pb( pb, e, NULL /* controls */, g_plg_identity[PLUGIN_RETROCL], 0 /* actions */ ); slapi_add_internal_pb (pb); slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_RESULT, &rc ); slapi_pblock_destroy(pb); if (rc == 0) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "created changelog database node\n"); } else if (rc == LDAP_ALREADY_EXISTS) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "changelog database node already existed\n"); } else { slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "Changelog LDBM backend could not be created (%d)\n", rc); return rc; } /* we need the changenumber indexed */ e = slapi_entry_alloc(); /* RETROCL_INDEX_DN is no need to be normalized. */ slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_INDEX_DN)); /* Set the objectclass attribute */ val.bv_val = "top"; val.bv_len = 3; slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "nsIndex"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); val.bv_val = "changenumber"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "cn", vals ); val.bv_val = "false"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nssystemindex", vals ); val.bv_val = "eq"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsindextype", vals ); val.bv_val = "integerOrderingMatch"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsMatchingRule", vals ); pb = slapi_pblock_new (); slapi_add_entry_internal_set_pb( pb, e, NULL /* controls */, g_plg_identity[PLUGIN_RETROCL], 0 /* actions */ ); slapi_add_internal_pb (pb); slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_RESULT, &rc ); slapi_pblock_destroy(pb); if (rc == 0) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "created changenumber index node\n"); } else if (rc == LDAP_ALREADY_EXISTS) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "changelog index node already existed\n"); } else { slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "Changelog LDBM backend changenumber index could not be created (%d)\n", rc); return rc; } return rc; }
/* * Function: retrocl_create_config * * Returns: LDAP_ * * Arguments: none * * Description: * This function is called if there was no mapping tree node or backend for * cn=changelog. */ int retrocl_create_config(void) { Slapi_PBlock *pb = NULL; Slapi_Entry *e; struct berval *vals[2]; struct berval val; int rc; char *mappingtree_dn = NULL; vals[0] = &val; vals[1] = NULL; /* Assume the mapping tree node is missing. It doesn't hurt to * attempt to add it if it already exists. You will see a warning * in the errors file when the referenced backend does not exist. */ e = slapi_entry_alloc(); /* This function converts the old DN style to the new one. */ mappingtree_dn = slapi_create_dn_string("%s", RETROCL_MAPPINGTREE_DN); if (NULL == mappingtree_dn) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "retrocl_create_config: failed to normalize " "mappingtree dn %s\n", RETROCL_MAPPINGTREE_DN); return LDAP_PARAM_ERROR; } slapi_entry_set_dn(e, mappingtree_dn); /* mappingtree_dn is consumed */ /* Set the objectclass attribute */ val.bv_val = "top"; val.bv_len = 3; slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "extensibleObject"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); /* Set the objectclass attribute */ val.bv_val = "nsMappingTree"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "objectclass", vals ); val.bv_val = "backend"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-state", vals ); val.bv_val = RETROCL_CHANGELOG_DN; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "cn", vals ); val.bv_val = "changelog"; val.bv_len = strlen(val.bv_val); slapi_entry_add_values( e, "nsslapd-backend", vals ); pb = slapi_pblock_new (); slapi_add_entry_internal_set_pb( pb, e, NULL /* controls */, g_plg_identity[PLUGIN_RETROCL], 0 /* actions */ ); slapi_add_internal_pb (pb); slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_RESULT, &rc ); slapi_pblock_destroy(pb); if (rc == 0) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "created changelog mapping tree node\n"); } else if (rc == LDAP_ALREADY_EXISTS) { slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, "changelog mapping tree node already existed\n"); } else { slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "cn=\"cn=changelog\",cn=mapping tree,cn=config could not be created (%d)\n", rc); return rc; } retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); if (retrocl_be_changelog == NULL) { /* This is not the nsslapd-changelogdir from cn=changelog4,cn=config */ char *bedir; bedir = retrocl_get_config_str(CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE); if (bedir == NULL) { /* none specified */ } rc = retrocl_create_be(bedir); slapi_ch_free ((void **)&bedir); if (rc != LDAP_SUCCESS && rc != LDAP_ALREADY_EXISTS) { return rc; } retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); } return LDAP_SUCCESS; }
/* * Extract the payload from a total update extended operation, * decode it, and produce a Slapi_Entry structure representing a new * entry to be added to the local database. */ static int decode_total_update_extop(Slapi_PBlock *pb, Slapi_Entry **ep) { BerElement *tmp_bere = NULL; Slapi_Entry *e = NULL; Slapi_Attr *attr = NULL; char *str = NULL; struct berval *extop_value = NULL; char *extop_oid = NULL; ber_len_t len; char *lasto; ber_tag_t tag; int rc; PRBool deleted; PR_ASSERT(NULL != pb); PR_ASSERT(NULL != ep); slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid); slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value); if ((NULL == extop_oid) || ((strcmp(extop_oid, REPL_NSDS50_REPLICATION_ENTRY_REQUEST_OID) != 0) && (strcmp(extop_oid, REPL_NSDS71_REPLICATION_ENTRY_REQUEST_OID) != 0)) || !BV_HAS_DATA(extop_value)) { /* Bogus */ goto loser; } if ((tmp_bere = ber_init(extop_value)) == NULL) { goto loser; } if ((e = slapi_entry_alloc()) == NULL) { goto loser; } if (ber_scanf(tmp_bere, "{") == LBER_ERROR) /* Begin outer sequence */ { goto loser; } /* The entry's uniqueid is first */ if (ber_scanf(tmp_bere, "a", &str) == LBER_ERROR) { goto loser; } slapi_entry_set_uniqueid(e, str); str = NULL; /* Slapi_Entry now owns the uniqueid */ /* The entry's DN is next */ if (ber_scanf(tmp_bere, "a", &str) == LBER_ERROR) { goto loser; } slapi_entry_set_dn(e, str); str = NULL; /* Slapi_Entry now owns the dn */ /* Get the attributes */ for ( tag = ber_first_element( tmp_bere, &len, &lasto ); tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET; tag = ber_next_element( tmp_bere, &len, lasto ) ) { if (my_ber_scanf_attr (tmp_bere, &attr, &deleted) != 0) { goto loser; } /* Add the attribute to the entry */ if (deleted) entry_add_deleted_attribute_wsi(e, attr); /* entry now owns attr */ else entry_add_present_attribute_wsi(e, attr); /* entry now owns attr */ attr = NULL; } if (ber_scanf(tmp_bere, "}") == LBER_ERROR) /* End sequence for this entry */ { goto loser; } /* Check for ldapsubentries and tombstone entries to set flags properly */ slapi_entry_attr_find(e, "objectclass", &attr); if (attr != NULL) { struct berval bv; bv.bv_val = "ldapsubentry"; bv.bv_len = strlen(bv.bv_val); if (slapi_attr_value_find(attr, &bv) == 0) { slapi_entry_set_flag(e, SLAPI_ENTRY_LDAPSUBENTRY); } bv.bv_val = SLAPI_ATTR_VALUE_TOMBSTONE; bv.bv_len = strlen(bv.bv_val); if (slapi_attr_value_find(attr, &bv) == 0) { slapi_entry_set_flag(e, SLAPI_ENTRY_FLAG_TOMBSTONE); } } /* If we get here, the entry is properly constructed. Return it. */ rc = 0; *ep = e; goto free_and_return; loser: rc = -1; /* slapi_ch_free accepts NULL pointer */ slapi_ch_free((void **)&str); if (attr != NULL) { slapi_attr_free (&attr); } if (NULL != e) { slapi_entry_free (e); } *ep = NULL; slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Error: could not decode extended " "operation containing entry for total update.\n"); free_and_return: if (NULL != tmp_bere) { ber_free(tmp_bere, 1); tmp_bere = NULL; } return rc; }