/* Are all the paged results requests timed out? */ int pagedresults_is_timedout(Connection *conn) { int i; PagedResults *prp = NULL; time_t ctime; int rc = 0; LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_is_timedout\n"); if (NULL == conn || 0 == conn->c_pagedresults.prl_count) { LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: -\n"); return rc; } ctime = current_time(); for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { prp = conn->c_pagedresults.prl_list + i; if (prp->pr_current_be && (prp->pr_timelimit > 0)) { if (ctime < prp->pr_timelimit) { LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: 0\n"); return 0; /* at least, one request is not timed out. */ } else { rc = 1; /* possibly timed out */ } } } LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_is_timedout: 1\n"); return rc; /* all requests are timed out. */ }
/* * pagedresults_cleanup_all frees the list. * return values * 0: not a simple paged result connection * 1: simple paged result and successfully abandoned */ int pagedresults_cleanup_all(Connection *conn, int needlock) { int rc = 0; int i; PagedResults *prp = NULL; LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_cleanup_all\n"); if (NULL == conn) { LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_cleanup_all: -\n"); return 0; } if (needlock) { PR_Lock(conn->c_mutex); } for (i = 0; conn->c_pagedresults.prl_list && i < conn->c_pagedresults.prl_maxlen; i++) { prp = conn->c_pagedresults.prl_list + i; if (prp->pr_current_be && prp->pr_search_result_set && prp->pr_current_be->be_search_results_release) { prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); rc = 1; } } slapi_ch_free((void **)&conn->c_pagedresults.prl_list); conn->c_pagedresults.prl_maxlen = 0; conn->c_pagedresults.prl_count = 0; if (needlock) { PR_Unlock(conn->c_mutex); } LDAPDebug1Arg(LDAP_DEBUG_TRACE, "<-- pagedresults_cleanup_all: %d\n", rc); return rc; }
/* This function returns the current Dirsync_Private that's inside Repl_Agmt ra as a ldap control. */ LDAPControl* windows_private_dirsync_control(const Repl_Agmt *ra) { LDAPControl *control = NULL; BerElement *ber; Dirsync_Private *dp; char iscritical = PR_TRUE; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_control\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); ber = ber_alloc(); ber_printf( ber, "{iio}", dp->dirsync_flags, dp->dirsync_maxattributecount, dp->dirsync_cookie ? dp->dirsync_cookie : "", dp->dirsync_cookie_len ); /* Use a regular directory server instead of a real AD - for testing */ if (getenv("WINSYNC_USE_DS")) { iscritical = PR_FALSE; } slapi_build_control( REPL_DIRSYNC_CONTROL_OID, ber, iscritical, &control); ber_free(ber,1); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_control\n" ); return control; }
/* paged results requests are in progress. */ int pagedresults_in_use(Connection *conn) { LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_in_use\n"); if (NULL == conn) { LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_in_use: -\n"); return 0; } LDAPDebug1Arg(LDAP_DEBUG_TRACE, "<-- pagedresults_in_use: %d\n", conn->c_pagedresults.prl_count); return conn->c_pagedresults.prl_count; }
void windows_private_set_api_cookie(Repl_Agmt *ra, void *api_cookie) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_api_cookie\n" ); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); dp->api_cookie = api_cookie; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_api_cookie\n" ); }
int windows_private_get_keep_raw_entry(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_keep_raw_entry\n" ); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_keep_raw_entry\n" ); return dp->keep_raw_entry; }
void *windows_private_get_api_cookie(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_api_cookie\n" ); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_api_cookie\n" ); return dp->api_cookie; }
void windows_plugin_init(Repl_Agmt *ra) { void *cookie = NULL; winsync_plugin_init_cb initfunc = NULL; LDAPDebug0Args( LDAP_DEBUG_PLUGIN, "--> windows_plugin_init_start -- begin\n"); /* if the function pointer array is null, get the functions - we will call init once per replication agreement, but will only grab the api once */ if(NULL == _WinSyncAPI) { if (slapi_apib_get_interface(WINSYNC_v2_0_GUID, &_WinSyncAPI) || (NULL == _WinSyncAPI)) { LDAPDebug1Arg( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- no windows plugin API registered for GUID [%s] -- end\n", WINSYNC_v2_0_GUID); } else if (_WinSyncAPI) { LDAPDebug1Arg( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- found windows plugin API registered for GUID [%s] -- end\n", WINSYNC_v2_0_GUID); maxapiidx = WINSYNC_PLUGIN_VERSION_2_END; } } if (NULL == _WinSyncAPI) { /* no v2 interface - look for v1 */ if (slapi_apib_get_interface(WINSYNC_v1_0_GUID, &_WinSyncAPI) || (NULL == _WinSyncAPI)) { LDAPDebug1Arg( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- no windows plugin API registered for GUID [%s] -- end\n", WINSYNC_v1_0_GUID); return; } else { LDAPDebug1Arg( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- found windows plugin API registered for GUID [%s] -- end\n", WINSYNC_v1_0_GUID); } } initfunc = (winsync_plugin_init_cb)_WinSyncAPI[WINSYNC_PLUGIN_INIT_CB]; if (initfunc) { cookie = (*initfunc)(windows_private_get_directory_subtree(ra), windows_private_get_windows_subtree(ra)); } windows_private_set_api_cookie(ra, cookie); LDAPDebug0Args( LDAP_DEBUG_PLUGIN, "<-- windows_plugin_init_start -- end\n"); return; }
void windows_private_set_one_way(const Repl_Agmt *ra, int value) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_one_way\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); dp->one_way = value; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_one_way\n" ); }
/* writes the current cookie into dse.ldif under the replication agreement entry returns: ldap result code of the operation. */ int windows_private_save_dirsync_cookie(const Repl_Agmt *ra) { Dirsync_Private *dp = NULL; Slapi_PBlock *pb = NULL; Slapi_DN* sdn = NULL; int rc = 0; Slapi_Mods *mods = NULL; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_save_dirsync_cookie\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); pb = slapi_pblock_new (); mods = windows_private_get_cookie_mod(dp, LDAP_MOD_REPLACE); sdn = slapi_sdn_dup( agmt_get_dn_byref(ra) ); slapi_modify_internal_set_pb_ext (pb, sdn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0); slapi_modify_internal_pb (pb); slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); if (rc == LDAP_NO_SUCH_ATTRIBUTE) { /* try again, but as an add instead */ slapi_mods_free(&mods); mods = windows_private_get_cookie_mod(dp, LDAP_MOD_ADD); slapi_modify_internal_set_pb_ext (pb, sdn, slapi_mods_get_ldapmods_byref(mods), NULL, NULL, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0); slapi_modify_internal_pb (pb); slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); } slapi_pblock_destroy (pb); slapi_mods_free(&mods); slapi_sdn_free(&sdn); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_save_dirsync_cookie\n" ); return rc; }
void windows_private_set_create_groups(const Repl_Agmt *ra, PRBool value) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_create_groups\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); dp->create_groups_from_dirsync = value; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_create_groups\n" ); }
PRBool windows_private_create_groups(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_create_groups\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_create_groups\n" ); return dp->create_groups_from_dirsync; }
/* Returns a copy of the Slapi_DN pointer, no need to free it */ const Slapi_DN* windows_private_get_directory_subtree (const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_replarea\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_directory_replarea\n" ); return dp->directory_subtree; }
int windows_private_get_iswin2k3(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_iswin2k3\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_iswin2k3\n" ); return dp->iswin2k3; }
void windows_private_set_iswin2k3(const Repl_Agmt *ra, int isit) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_iswin2k3\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); dp->iswin2k3 = isit; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_iswin2k3\n" ); }
void windows_private_null_dirsync_cookie(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_null_dirsync_control\n" ); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); dp->dirsync_cookie_len = 0; slapi_ch_free_string(&dp->dirsync_cookie); dp->dirsync_cookie = NULL; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_null_dirsync_control\n" ); }
const char * windows_private_get_windows_domain(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_windows_domain\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_windows_domain\n" ); return dp->windows_domain; }
static void windows_private_set_windows_domain(const Repl_Agmt *ra, char *domain) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_windows_domain\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); dp->windows_domain = domain; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_windows_domain\n" ); }
time_t windows_private_get_sync_interval(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_sync_interval\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_sync_interval\n" ); return dp->sync_interval; }
PRBool windows_private_dirsync_has_more(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_dirsync_has_more\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_dirsync_has_more\n" ); return dp->dirsync_cookie_has_more; }
Dirsync_Private* windows_private_new() { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_new\n" ); dp = (Dirsync_Private *)slapi_ch_calloc(sizeof(Dirsync_Private),1); dp->dirsync_maxattributecount = -1; dp->directory_filter = NULL; dp->deleted_filter = NULL; dp->sync_interval = PERIODIC_DIRSYNC_INTERVAL; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_new\n" ); return dp; }
/* Takes a copy of the sdn passed in */ void windows_private_set_directory_subtree (const Repl_Agmt *ra,Slapi_DN* sdn ) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_directory_replarea\n" ); PR_ASSERT(ra); PR_ASSERT(sdn); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); slapi_sdn_free(&dp->directory_subtree); dp->directory_subtree = sdn; LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_directory_replarea\n" ); }
/* reset all timeout */ int pagedresults_reset_timedout(Connection *conn) { int i; PagedResults *prp = NULL; if (NULL == conn) { return 0; } LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_reset_timedout\n"); for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { prp = conn->c_pagedresults.prl_list + i; prp->pr_timelimit = 0; } LDAPDebug0Args(LDAP_DEBUG_TRACE, "<-- pagedresults_reset_timedout: 0\n"); return 0; }
void windows_private_set_sync_interval(Repl_Agmt *ra, char *str) { Dirsync_Private *dp; time_t tmpval = 0; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_sync_interval\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); if (str && (tmpval = (time_t)atol(str))) { dp->sync_interval = tmpval; } LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_sync_interval\n" ); }
/* this is passin - windows_private owns the pointer, not a copy */ void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_raw_entry\n" ); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); /* If the keep raw entry flag is set, just free the passed * in entry and leave the current raw entry in place. */ if (windows_private_get_keep_raw_entry(ra)) { slapi_entry_free(e); } else { slapi_entry_free(dp->raw_entry); dp->raw_entry = e; } LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_raw_entry\n" ); }
/* Returns a copy of the Slapi_Filter pointer. The caller should not free it */ Slapi_Filter* windows_private_get_directory_filter(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_filter\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); if (dp->directory_filter == NULL) { char *string_filter = slapi_ch_strdup("(&(|(objectclass=ntuser)(objectclass=ntgroup))(ntUserDomainId=*))"); /* The filter gets freed in windows_agreement_delete() */ dp->directory_filter = slapi_str2filter( string_filter ); slapi_ch_free_string(&string_filter); } LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_directory_filter\n" ); return dp->directory_filter; }
/* Returns a copy of the Slapi_Filter pointer. The caller should not free it */ Slapi_Filter* windows_private_get_deleted_filter(const Repl_Agmt *ra) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_deleted_filter\n" ); PR_ASSERT(ra); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); if (dp->deleted_filter == NULL) { char *string_filter = slapi_ch_strdup("(isdeleted=*)"); /* The filter gets freed in windows_agreement_delete() */ dp->deleted_filter = slapi_str2filter( string_filter ); slapi_ch_free_string(&string_filter); } LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_get_deleted_filter\n" ); return dp->deleted_filter; }
void windows_agreement_delete(Repl_Agmt *ra) { Dirsync_Private *dp = (Dirsync_Private *) agmt_get_priv(ra); LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_delete\n" ); PR_ASSERT(dp != NULL); winsync_plugin_call_destroy_agmt_cb(ra, dp->directory_subtree, dp->windows_subtree); slapi_sdn_free(&dp->directory_subtree); slapi_sdn_free(&dp->windows_subtree); slapi_filter_free(dp->directory_filter, 1); slapi_filter_free(dp->deleted_filter, 1); slapi_entry_free(dp->raw_entry); dp->raw_entry = NULL; dp->api_cookie = NULL; slapi_ch_free((void **)dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_delete\n" ); }
/* * If "dn" is passed, get_entry returns an entry which dn is "dn". * If "dn" is not passed, it returns an entry which dn is set in * SLAPI_TARGET_SDN in pblock. * Note: pblock is not mandatory for get_entry (e.g., new_passwdPolicy). */ Slapi_Entry *get_entry ( Slapi_PBlock *pb, const char *dn) { int search_result = 0; Slapi_Entry *retentry = NULL; Slapi_DN *target_sdn = NULL; const char *target_dn = dn; Slapi_DN sdn; if (pb) { slapi_pblock_get( pb, SLAPI_TARGET_SDN, &target_sdn ); if (target_dn == NULL) { target_dn = slapi_sdn_get_dn(target_sdn); } } if (target_dn == NULL) { LDAPDebug0Args(LDAP_DEBUG_TRACE, "WARNING: 'get_entry' - no dn specified.\n"); goto bail; } if (target_dn == dn) { /* target_dn is NOT from target_sdn */ slapi_sdn_init_dn_byref(&sdn, target_dn); target_sdn = &sdn; } search_result = slapi_search_internal_get_entry(target_sdn, NULL, &retentry, pw_get_componentID()); if (search_result != LDAP_SUCCESS) { LDAPDebug2Args(LDAP_DEBUG_TRACE, "WARNING: 'get_entry' can't find entry '%s', err %d\n", target_dn, search_result); } if (target_dn == dn) { /* target_dn is NOT from target_sdn */ slapi_sdn_done(&sdn); } bail: return retentry; }
/* * op_shared_rename() -- common frontend code for modDN operations. * * Beware: this function resets the following pblock elements that were * set by the caller: * * SLAPI_MODRDN_TARGET_SDN * SLAPI_MODRDN_NEWRDN * SLAPI_MODRDN_NEWSUPERIOR_SDN */ static void op_shared_rename(Slapi_PBlock *pb, int passin_args) { char *dn, *newrdn, *newdn = NULL; const char *newsuperior; char **rdns; int deloldrdn; Slapi_Backend *be = NULL; Slapi_DN *origsdn = NULL; Slapi_Mods smods; int internal_op, repl_op, lastmod; Slapi_Operation *operation; Slapi_Entry *referral; char errorbuf[BUFSIZ]; int err; char *proxydn = NULL; char *proxystr = NULL; int proxy_err = LDAP_SUCCESS; char *errtext = NULL; Slapi_DN *sdn = NULL; Slapi_DN *newsuperiorsdn = NULL; slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET, &dn); slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn); slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperiorsdn); slapi_pblock_get(pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn); slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op); slapi_pblock_get (pb, SLAPI_OPERATION, &operation); slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &origsdn); internal_op= operation_is_flag_set(operation, OP_FLAG_INTERNAL); /* * If ownership has not been passed to this function, we replace the * string input fields within the pblock with strdup'd copies. Why? * Because some pre- and post-op plugins may change them, and the * convention is that plugins should place a malloc'd string in the * pblock. Therefore, we need to be able to retrieve and free them * later. But the callers of the internal modrdn calls are promised * that we will not free these parameters... so if passin_args is * zero, we need to make copies. * * In the case of SLAPI_MODRDN_TARGET_SDN and SLAPI_MODRDN_NEWSUPERIOR_SDN, * we replace the existing values with normalized values (because plugins * expect these DNs to be normalized). */ if (NULL == origsdn) { sdn = slapi_sdn_new_dn_byval(dn); slapi_pblock_set(pb, SLAPI_MODRDN_TARGET_SDN, sdn); } if (passin_args) { if (NULL == sdn) { /* origsdn is not NULL, so use it. */ sdn = origsdn; } } else { if (NULL == sdn) { sdn = slapi_sdn_dup(origsdn); } newrdn = slapi_ch_strdup(newrdn); newsuperiorsdn = slapi_sdn_dup(newsuperiorsdn); slapi_pblock_set(pb, SLAPI_MODRDN_TARGET_SDN, sdn); slapi_pblock_set(pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn); slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, newsuperiorsdn); } /* normdn = slapi_sdn_get_dn(sdn); */ newsuperior = slapi_sdn_get_dn(newsuperiorsdn); /* get the proxy auth dn if the proxy auth control is present */ proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext); /* * first, log the operation to the access log, * then check rdn and newsuperior, * and - if applicable - log reason of any error to the errors log */ if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)) { if (proxydn) { proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); } if ( !internal_op ) { slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, newrdn ? newrdn : "(null)", newsuperior ? newsuperior : "(null)", proxystr ? proxystr : ""); } else { slapi_log_access(LDAP_DEBUG_ARGS, "conn=%s op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, dn, newrdn ? newrdn : "(null)", newsuperior ? newsuperior : "(null)", proxystr ? proxystr : ""); } } /* If we encountered an error parsing the proxy control, return an error * to the client. We do this here to ensure that we log the operation first. */ if (proxy_err != LDAP_SUCCESS) { send_ldap_result(pb, proxy_err, NULL, errtext, 0, NULL); goto free_and_return_nolock; } /* check that the rdn is formatted correctly */ if ((rdns = slapi_ldap_explode_rdn(newrdn, 0)) == NULL) { if ( !internal_op ) { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%" NSPRIu64 " op=%d MODRDN invalid new RDN (\"%s\")\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, (NULL == newrdn) ? "(null)" : newrdn); } else { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%s op=%d MODRDN invalid new RDN (\"%s\")\n", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, (NULL == newrdn) ? "(null)" : newrdn); } send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid RDN", 0, NULL); goto free_and_return_nolock; } else { slapi_ldap_value_free(rdns); } /* check if created attributes are used in the new RDN */ /* check_rdn_for_created_attrs ignores the cases */ if (check_rdn_for_created_attrs((const char *)newrdn)) { send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid attribute in RDN", 0, NULL); goto free_and_return_nolock; } /* check that the dn is formatted correctly */ err = slapi_dn_syntax_check(pb, newsuperior, 1); if (err) { LDAPDebug0Args(LDAP_DEBUG_ARGS, "Syntax check of newSuperior failed\n"); if (!internal_op) { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%" NSPRIu64 " op=%d MODRDN invalid new superior (\"%s\")", pb->pb_conn->c_connid, pb->pb_op->o_opid, newsuperior ? newsuperior : "(null)"); } else { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%s op=%d MODRDN invalid new superior (\"%s\")", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, newsuperior ? newsuperior : "(null)"); } send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "newSuperior does not look like a DN", 0, NULL); goto free_and_return_nolock; } if (newsuperior != NULL) { LDAPDebug(LDAP_DEBUG_ARGS, "do_moddn: newsuperior (%s)\n", newsuperior, 0, 0); } /* target spec is used to decide which plugins are applicable for the operation */ operation_set_target_spec (pb->pb_op, sdn); /* * Construct the new DN (code sdn from backend * and modified to handle newsuperior) */ newdn = slapi_moddn_get_newdn(sdn, newrdn, newsuperior); /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ /* slapi_mapping_tree_select_and_check ignores the case of newdn * which is generated using newrdn above. */ if ((err = slapi_mapping_tree_select_and_check(pb, newdn, &be, &referral, errorbuf)) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, errorbuf, 0, NULL); goto free_and_return_nolock; } if (referral) { int managedsait; slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait); if (managedsait) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot update referral", 0, NULL); slapi_entry_free(referral); goto free_and_return; } send_referrals_from_entry(pb,referral); slapi_entry_free(referral); goto free_and_return; } slapi_pblock_set(pb, SLAPI_BACKEND, be); /* can get lastmod only after backend is selected */ slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod); /* if it is a replicated operation - leave lastmod attributes alone */ slapi_mods_init (&smods, 2); if (!repl_op && lastmod) { modify_update_last_modified_attr(pb, &smods); slapi_pblock_set(pb, SLAPI_MODIFY_MODS, (void*)slapi_mods_get_ldapmods_passout(&smods)); } else { slapi_mods_done (&smods); } /* * call the pre-modrdn plugins. if they succeed, call * the backend modrdn function. then call the * post-modrdn plugins. */ if (plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN : SLAPI_PLUGIN_PRE_MODRDN_FN) == 0) { int rc= LDAP_OPERATIONS_ERROR; slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database); set_db_default_result_handlers(pb); if (be->be_modrdn != NULL) { if ((rc = (*be->be_modrdn)(pb)) == 0) { Slapi_Entry *pse; Slapi_Entry *ecopy; /* we don't perform acl check for internal operations */ /* dont update aci store for remote acis */ if ((!internal_op) && (!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA))) plugin_call_acl_mods_update (pb, SLAPI_OPERATION_MODRDN); if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT)) write_audit_log_entry(pb); /* Record the operation in the audit log */ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy); /* GGOODREPL persistent search system needs the changenumber, oops. */ do_ps_service(pse, ecopy, LDAP_CHANGETYPE_MODDN, 0); } } else { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL); } slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc); plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN : SLAPI_PLUGIN_POST_MODRDN_FN); } free_and_return: if (be) slapi_be_Unlock(be); free_and_return_nolock: { /* Free up everything left in the PBlock */ Slapi_Entry *pse; Slapi_Entry *ecopy; LDAPMod **mods; char *s; if (passin_args) { if (NULL == origsdn) { slapi_sdn_free(&sdn); } } else { slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sdn); slapi_sdn_free(&sdn); /* get newrdn to free the string */ slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn); slapi_ch_free_string(&newrdn); slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperiorsdn); slapi_sdn_free(&newsuperiorsdn); } slapi_ch_free_string(&newdn); slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy); slapi_entry_free(ecopy); slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); slapi_entry_free(pse); slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ); ldap_mods_free( mods, 1 ); slapi_ch_free_string(&proxydn); slapi_ch_free_string(&proxystr); slapi_pblock_get(pb, SLAPI_URP_NAMING_COLLISION_DN, &s); slapi_ch_free((void **)&s); } }