Beispiel #1
0
/*
 * findSubtreeAndSearch - walk up the tree to find an entry with
 * the marker object class; if found, call search from there and
 * return the result it returns
 *
 * If 'attr' is NULL, the values are taken from 'values'.
 * If 'attr' is non-NULL, the values are taken from 'attr'.
 *
 * Return:
 *   LDAP_SUCCESS - no matches, or the attribute matches the
 *     target dn.
 *   LDAP_CONSTRAINT_VIOLATION - an entry was found that already
 *     contains the attribute value.
 *   LDAP_OPERATIONS_ERROR - a server failure.
 */
static int
findSubtreeAndSearch(Slapi_DN *parentDN, const char *attrName, Slapi_Attr *attr,
  struct berval **values, const char *requiredObjectClass, Slapi_DN *target,
  const char *markerObjectClass)
{
  int result = LDAP_SUCCESS;
  Slapi_PBlock *spb = NULL;
  Slapi_DN *curpar = slapi_sdn_new();
  Slapi_DN *newpar = NULL;

  slapi_sdn_get_parent(parentDN, curpar);
  while ((curpar != NULL) && (slapi_sdn_get_dn(curpar) != NULL))
  {
        if ((spb = dnHasObjectClass(curpar, markerObjectClass)))
        {
          freePblock(spb);
          /*
           * Do the search.   There is no entry that is allowed
           * to have the attribute already.
           */
          result = search(curpar, attrName, attr, values, requiredObjectClass,
                          target);
          break;
        }
        newpar = slapi_sdn_new();
        slapi_sdn_copy(curpar, newpar);
        slapi_sdn_get_parent(newpar, curpar);
        slapi_sdn_free(&newpar);
  }
  slapi_sdn_free(&curpar);
  return result;
}
Beispiel #2
0
/*
 * searchAllSubtrees - search all subtrees in argv for entries
 *   with a named attribute matching the list of values, by
 *   calling search for each one.
 *
 * If 'attr' is NULL, the values are taken from 'values'.
 * If 'attr' is non-NULL, the values are taken from 'attr'.
 *
 * Return:
 *   LDAP_SUCCESS - no matches, or the attribute matches the
 *     target dn.
 *   LDAP_CONSTRAINT_VIOLATION - an entry was found that already
 *     contains the attribute value.
 *   LDAP_OPERATIONS_ERROR - a server failure.
 */
static int
searchAllSubtrees(int argc, char *argv[], const char *attrName,
  Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass,
  Slapi_DN *dn)
{
  int result = LDAP_SUCCESS;

  /*
   * For each DN in the managed list, do uniqueness checking if
   * the target DN is a subnode in the tree.
   */
  for(;argc > 0;argc--,argv++)
  {
    Slapi_DN *sufdn = slapi_sdn_new_dn_byref(*argv);
    /*
     * The DN should already be normalized, so we don't have to
     * worry about that here.
     */
    if (slapi_sdn_issuffix(dn, sufdn)) {
      result = search(sufdn, attrName, attr, values, requiredObjectClass, dn);
      slapi_sdn_free(&sufdn);
      if (result) break;
    } else {
      slapi_sdn_free(&sufdn);
    }
  }
  return result;
}
Beispiel #3
0
/* if vs is given, delete only those values - otherwise, delete all values */
void
replica_updatedn_list_delete(ReplicaUpdateDNList list, const Slapi_ValueSet *vs)
{
	PLHashTable *hash = list;
	if (!vs || slapi_valueset_count(vs) == 0) { /* just delete everything */
		PL_HashTableEnumerateEntries(hash, replica_destroy_hash_entry, NULL);
	} else {
		Slapi_ValueSet *vs_nc = (Slapi_ValueSet *)vs; /* cast away const */
		Slapi_Value *val = NULL;
		int index = 0;
		for (index = slapi_valueset_first_value(vs_nc, &val); val;
			 index = slapi_valueset_next_value(vs_nc, index, &val)) {
			Slapi_DN *dn = slapi_sdn_new_dn_byval(slapi_value_get_string(val));
			/* locate object */
			Slapi_DN *deldn = (Slapi_DN *)PL_HashTableLookup(hash, slapi_sdn_get_ndn(dn));     
			if (deldn == NULL)
			{
				slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_updatedn_list_delete -"
								"Update DN with value (%s) is not in the update DN list.\n",
								slapi_sdn_get_ndn(dn));
			} else {
				/* remove from hash */
				PL_HashTableRemove(hash, slapi_sdn_get_ndn(dn));
				/* free the pointer */
				slapi_sdn_free(&deldn);
			}
			/* free the temp dn */
			slapi_sdn_free(&dn);
		}
	}

	return;
}
Beispiel #4
0
int
acct_policy_close( Slapi_PBlock *pb )
{
	int rc = 0;

	slapi_destroy_rwlock(config_rwlock);
	config_rwlock = NULL;
	slapi_sdn_free(&_PluginDN);
	slapi_sdn_free(&_ConfigAreaDN);
	free_config();

	return rc;
}
Beispiel #5
0
static char *
get_rdn_plus_uniqueid(char *sessionid, const char *olddn, const char *uniqueid)
{
	char *newrdn;
	/* Check if the RDN already contains the Unique ID */
	Slapi_DN *sdn= slapi_sdn_new_dn_byval(olddn);
	Slapi_RDN *rdn= slapi_rdn_new();
	slapi_sdn_get_rdn(sdn,rdn);
	PR_ASSERT(uniqueid!=NULL);
	if(slapi_rdn_contains(rdn,SLAPI_ATTR_UNIQUEID,uniqueid,strlen(uniqueid)))
	{
		/* The Unique ID is already in the RDN.
		 * This is a highly improbable collision.
		 * It suggests that a duplicate UUID was generated.
		 * This will cause replication divergence and will
		 * require admin intercession
		 */
		slapi_log_error(SLAPI_LOG_FATAL, sessionid,
				"Annotated DN %s has naming conflict\n", olddn );
		newrdn= NULL;
	}
	else
	{
		slapi_rdn_add(rdn,SLAPI_ATTR_UNIQUEID,uniqueid);
		newrdn= slapi_ch_strdup(slapi_rdn_get_rdn(rdn));
	}
	slapi_sdn_free(&sdn);
	slapi_rdn_free(&rdn);
	return newrdn;
}
Beispiel #6
0
/*
 * Create a new protocol instance.
 */
Repl_Protocol *
prot_new(Repl_Agmt *agmt, int protocol_state)
{
	Slapi_DN *replarea_sdn = NULL;
	Repl_Protocol *rp = (Repl_Protocol *)slapi_ch_calloc(1, sizeof(Repl_Protocol));

	rp->prp_incremental = rp->prp_total = rp->prp_active_protocol = NULL;
	if (protocol_state == STATE_PERFORMING_TOTAL_UPDATE)
	{
		rp->state = STATE_PERFORMING_TOTAL_UPDATE;
	}
	else
	{
		rp->state = STATE_PERFORMING_INCREMENTAL_UPDATE;
	}
	rp->next_state = STATE_PERFORMING_INCREMENTAL_UPDATE; 
	if ((rp->lock = PR_NewLock()) == NULL)
	{
		goto loser;
	}
	rp->agmt = agmt;
	rp->conn = NULL;
	/* Acquire the local replica object */
	replarea_sdn = agmt_get_replarea(agmt);
	rp->replica_object = replica_get_replica_from_dn(replarea_sdn);
	if (NULL == rp->replica_object)
	{
		/* Whoa, no local replica!?!? */
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
			"prot_new - %s: Unable to locate replica object for local replica %s\n",
			agmt_get_long_name(agmt),
			slapi_sdn_get_dn(replarea_sdn));
		goto loser;
	}

	if (get_agmt_agreement_type(agmt) == REPLICA_TYPE_MULTIMASTER)
	{
		rp->prp_incremental = private_protocol_factory(rp, PROTOCOL_5_INCREMENTAL);
		rp->prp_total = private_protocol_factory(rp, PROTOCOL_5_TOTAL);
		rp->delete_conn = conn_delete;
	} 
	else if  (get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS)
	{
		rp->prp_incremental = private_protocol_factory(rp, PROTOCOL_WINDOWS_INCREMENTAL);
		rp->prp_total = private_protocol_factory(rp, PROTOCOL_WINDOWS_TOTAL);
		rp->delete_conn = windows_conn_delete;
	}
	/* XXXggood register callback handlers for entries updated, and
		schedule window enter/leave. */
	
	goto done;

loser:
	prot_delete(&rp);

done:
	slapi_sdn_free(&replarea_sdn);

	return rp;
}
Beispiel #7
0
/*
  Creates global config structure from config entry at plugin startup
*/
int
acct_policy_load_config_startup( Slapi_PBlock* pb, void* plugin_id ) {
	acctPluginCfg *newcfg;
	Slapi_Entry *config_entry = NULL;
	Slapi_DN *config_sdn = NULL;
	int rc;

	/* Retrieve the config entry */
	config_sdn = slapi_sdn_new_normdn_byref( PLUGIN_CONFIG_DN );
	rc = slapi_search_internal_get_entry( config_sdn, NULL, &config_entry,
		plugin_id);
	slapi_sdn_free( &config_sdn );

	if( rc != LDAP_SUCCESS || config_entry == NULL ) {
		slapi_log_err(SLAPI_LOG_ERR, PLUGIN_NAME,
			"acct_policy_load_config_startup - Failed to retrieve configuration entry %s: %d\n",
			PLUGIN_CONFIG_DN, rc );
		return( -1 );
	}
	config_wr_lock();
	free_config();
	newcfg = get_config();
	rc = acct_policy_entry2config( config_entry, newcfg );
	config_unlock();

	slapi_entry_free( config_entry );

	return( rc );
}
Beispiel #8
0
/*
 * Note: when we add the new object, we have a reference to it. We hold
 * on to this reference until the agreement is deleted (or until the
 * server is shut down).
 */
int
add_new_agreement(Slapi_Entry *e)
{
    int rc = 0;
    Repl_Agmt *ra = agmt_new_from_entry(e);
    Slapi_DN *replarea_sdn = NULL;
    Replica *replica = NULL;
    Object *repl_obj = NULL;
    Object *ro = NULL;

    /* tell search result handler callback this entry was not sent */
    if (ra == NULL)
        return 1;

    ro = object_new((void *)ra, agmt_delete);
    objset_add_obj(agmt_set, ro);
    object_release(ro); /* Object now owned by objset */

    /* get the replica for this agreement */
    replarea_sdn = agmt_get_replarea(ra);
    repl_obj = replica_get_replica_from_dn(replarea_sdn);
    slapi_sdn_free(&replarea_sdn);
    if (repl_obj) {
        replica = (Replica*)object_get_data (repl_obj);
    }

    rc = replica_start_agreement(replica, ra);

    if (repl_obj) object_release(repl_obj);

    return rc;
}
Beispiel #9
0
int
repl_session_plugin_call_post_acquire_cb(const Repl_Agmt *ra, int is_total,
                                         const char *data_guid, const struct berval *data)
{
    int rc = 0;
    Slapi_DN *replarea = NULL;

    repl_session_plugin_post_acquire_cb thefunc =
        (_ReplSessionAPI && _ReplSessionAPI[REPL_SESSION_PLUGIN_POST_ACQUIRE_CB]) ?
        (repl_session_plugin_post_acquire_cb)_ReplSessionAPI[REPL_SESSION_PLUGIN_POST_ACQUIRE_CB] :
        NULL;

    if (thefunc) {
        replarea = agmt_get_replarea(ra);
        if (!replarea) {
            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
                    "repl_session_plugin_call_post_acquire_cb - Aborted - No replication area\n");
            return 1;
        }
        rc = (*thefunc)(agmt_get_priv(ra), replarea, is_total, data_guid, data);
        slapi_sdn_free(&replarea);
    }

    return rc;
}
Beispiel #10
0
void
repl_session_plugin_call_agmt_init_cb(Repl_Agmt *ra)
{
    void *cookie = NULL;
    Slapi_DN *replarea = NULL;
    repl_session_plugin_agmt_init_cb initfunc = NULL;

    slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name,
            "repl_session_plugin_call_agmt_init_cb - Begin\n");

    if (_ReplSessionAPI) {
        initfunc = (repl_session_plugin_agmt_init_cb)_ReplSessionAPI[REPL_SESSION_PLUGIN_AGMT_INIT_CB];
    }
    if (initfunc) {
        replarea = agmt_get_replarea(ra);
        if (!replarea) {
            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
                    "repl_session_plugin_call_agmt_init_cb- Aborted - No replication area\n");
            return;
        }
        cookie = (*initfunc)(replarea);
        slapi_sdn_free(&replarea);
    }

    agmt_set_priv(ra, cookie);

    slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name, "repl_session_plugin_call_agmt_init_cb - End\n");

    return;
}
Beispiel #11
0
/*
 * Check if User Private Groups are enabled in given IPA domain
 * Returns: 0 - UPG are enabled
 *          1 - UPG are disabled
 *         -1 - some sort of error
 */
static int
ipa_winsync_upg_enabled(const Slapi_DN *ds_subtree)
{
    int ret = -1;
    int rc;
    char * dn = NULL;
    Slapi_Entry *entry = NULL;
    Slapi_Backend *be;
    const Slapi_DN *ds_suffix = NULL;
    Slapi_DN *sdn = NULL;
    const char *attrs_list[] = {IPA_WINSYNC_UPG_DEF_ATTR, 0};
    char * value = NULL;

    /* find ancestor base DN */
    be = slapi_be_select(ds_subtree);
    ds_suffix = slapi_be_getsuffix(be, 0);
    if (ds_suffix == NULL) {
        LOG_FATAL("Invalid DS subtree [%s]\n", slapi_sdn_get_dn(ds_subtree));
        goto done;
    }

    dn = slapi_ch_smprintf(IPA_WINSYNC_UPG_DEF_DN, slapi_sdn_get_dn(ds_suffix));

    if (!dn) {
        LOG_OOM();
        goto done;
    }

    sdn = slapi_sdn_new_dn_byref(dn);
    rc = slapi_search_internal_get_entry(sdn, (char **) attrs_list, &entry,
                                         ipa_winsync_get_plugin_identity());

    if (rc) {
        LOG("failed to retrieve UPG definition (%s) with rc %d\n", dn, rc);
        goto done;
    }

    value = slapi_entry_attr_get_charptr(entry, IPA_WINSYNC_UPG_DEF_ATTR);

    if (!value) {
        LOG("failed to read %s from UPG definition (%s)\n",
             IPA_WINSYNC_UPG_DEF_ATTR, dn);
        goto done;
    }

    if (strstr(value, IPA_WINSYNC_UPG_DEF_DISABLED) == NULL) {
        ret = 0;
    } else {
        ret = 1;
    }

done:
    slapi_ch_free_string(&dn);
    slapi_sdn_free(&sdn);
    slapi_ch_free_string(&value);
    slapi_entry_free(entry);

    return ret;
}
Beispiel #12
0
static void
Delete_Pam_PassthruSuffix(Pam_PassthruSuffix *one)
{
    if (one) {
        slapi_sdn_free(&one->pamptsuffix_dn);
        slapi_ch_free((void **)&one);
    }
}
Beispiel #13
0
static void
memberof_free_scope(Slapi_DN **scopes, int *count)
{
	int i = 0;

	while(scopes && scopes[i]){
		slapi_sdn_free(&scopes[i]);
		i++;
	}
	slapi_ch_free((void**)&scopes);
	*count = 0;
}
Beispiel #14
0
Object* agmtlist_get_next_agreement_for_replica (Replica *r, Object *prev)
{
    const Slapi_DN *replica_root;
    Slapi_DN *agmt_root;
    Object *obj;
    Repl_Agmt *agmt;

    if (r == NULL)
    {
        /* ONREPL - log error */
        return NULL;
    }

    replica_root = replica_get_root(r);  

    if (prev)
        obj = objset_next_obj(agmt_set, prev);   
    else
        obj = objset_first_obj(agmt_set);
        
    while (obj)
    {
        agmt = (Repl_Agmt*)object_get_data (obj);
        PR_ASSERT (agmt);

        agmt_root = agmt_get_replarea(agmt);
        PR_ASSERT (agmt_root);

        if (slapi_sdn_compare (replica_root, agmt_root) == 0)
        {
            slapi_sdn_free (&agmt_root);
            return obj;
        }

        slapi_sdn_free (&agmt_root);
        obj = objset_next_obj(agmt_set, obj);
    }

    return NULL;
}
Beispiel #15
0
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" );

}
Beispiel #16
0
/*  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;
}
Beispiel #17
0
/* this function called for each hash node during hash destruction */
static PRIntn
replica_destroy_hash_entry(PLHashEntry *he, PRIntn index, void *arg)
{
    Slapi_DN *dn = NULL;
    
    if (he == NULL)
        return HT_ENUMERATE_NEXT;

    dn = (Slapi_DN *)he->value;
    PR_ASSERT (dn);

    slapi_sdn_free(&dn);

    return HT_ENUMERATE_REMOVE;
}
Beispiel #18
0
/* 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" );
}
Beispiel #19
0
/* Searches the dn in directory,
 *  If found	 : fills in slapi_entry structure and returns 0
 *  If NOT found : returns the search result as LDAP_NO_SUCH_OBJECT
 */
int ipapwd_getEntry(const char *dn, Slapi_Entry **e2, char **attrlist)
{
    Slapi_DN *sdn;
    int search_result = 0;

    LOG_TRACE("=>\n");

    sdn = slapi_sdn_new_dn_byref(dn);
    search_result = slapi_search_internal_get_entry(sdn, attrlist, e2,
                                                    ipapwd_plugin_id);
    if (search_result != LDAP_SUCCESS) {
        LOG_TRACE("No such entry-(%s), err (%d)\n", dn, search_result);
    }

    slapi_sdn_free(&sdn);
    LOG_TRACE("<= result: %d\n", search_result);
    return search_result;
}
Beispiel #20
0
/*
 * __aclanom_del_profile
 *
 *	Cleanup the anonymous user's profile we have.
 * 
 *	ASSUMPTION: A WRITE LOCK HAS BEEN OBTAINED
 *
 */
void
aclanom__del_profile (int closing)
{
	int						i;
	struct	anom_profile	*a_profile;


	if ( (a_profile = acl_anom_profile) == NULL ) {
		return;
	}

	for ( i=0; i < a_profile->anom_numacls; i++ ) {
		int	j = 0;
		char	**destArray = a_profile->anom_targetinfo[i].anom_targetAttrs;

		/* Deallocate target */
		slapi_sdn_free ( &a_profile->anom_targetinfo[i].anom_target );
		
		/* Deallocate filter */
		if ( a_profile->anom_targetinfo[i].anom_filter )
			slapi_filter_free ( a_profile->anom_targetinfo[i].anom_filter, 1 );

		/* Deallocate attrs */
		if ( destArray ) {
			while ( destArray[j] ) {
				slapi_ch_free ( (void **) &destArray[j] );
				j++;
			}
			slapi_ch_free ( (void **) &destArray );
		}
		a_profile->anom_targetinfo[i].anom_targetAttrs = NULL;
		a_profile->anom_targetinfo[i].anom_type = 0;
        a_profile->anom_targetinfo[i].anom_access = 0;
	}
	a_profile->anom_numacls = 0;

	if(closing){
		slapi_destroy_rwlock(anom_rwlock);
		anom_rwlock = NULL;
		slapi_ch_free((void **)&acl_anom_profile);
	}

	/* Don't clean the signatue */
}
Beispiel #21
0
/* 
 * add  a list of dns to the ReplicaUpdateDNList.
 * The dn could be the dn of a group, so get the entry 
 * and check the objectclass. If it is a static or dynamic group
 * generate the list of member dns and recursively call 
 * replica_updatedn_list_add().
 * The dn of the group is added to the list, so it will detect 
 * potential circular group definitions
 */
void
replica_updatedn_list_add_ext(ReplicaUpdateDNList list, const Slapi_ValueSet *vs, int group_update)
{
	PLHashTable *hash = list;
	Slapi_ValueSet *vs_nc = (Slapi_ValueSet *)vs; /* cast away const */
	Slapi_Value *val = NULL;
	int index = 0;

	PR_ASSERT(list && vs);

	for (index = slapi_valueset_first_value(vs_nc, &val); val;
		 index = slapi_valueset_next_value(vs_nc, index, &val)) {
		Slapi_DN *dn = slapi_sdn_new_dn_byval(slapi_value_get_string(val));
		const char *ndn = slapi_sdn_get_ndn(dn);

		/* make sure that the name is unique */
		if (PL_HashTableLookup(hash, ndn) != NULL)
		{
			slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_updatedn_list_add - "
							"Update DN with value (%s) already in the update DN list\n",
							ndn);
			slapi_sdn_free(&dn);
		} else {
			Slapi_ValueSet *members = NULL;
			PL_HashTableAdd(hash, ndn, dn);
			/* add it, even if it is a group dn, this will 
			 * prevent problems with circular group definitions
			 * then check if it has mor members to add */
			if (group_update) {
				members = replica_updatedn_list_get_members(dn);
				if (members) {
					replica_updatedn_list_add_ext(list, members, 1);
					/* free members */
					slapi_valueset_free(members);
				}
			}
		}
	}

	return;
}
Beispiel #22
0
void
repl_session_plugin_call_destroy_agmt_cb(const Repl_Agmt *ra)
{
    Slapi_DN *replarea = NULL;

    repl_session_plugin_destroy_agmt_cb thefunc =
        (_ReplSessionAPI && _ReplSessionAPI[REPL_SESSION_PLUGIN_DESTROY_AGMT_CB]) ?
        (repl_session_plugin_destroy_agmt_cb)_ReplSessionAPI[REPL_SESSION_PLUGIN_DESTROY_AGMT_CB] :
        NULL;

    if (thefunc) {
        replarea = agmt_get_replarea(ra);
        if (!replarea) {
            slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
                    "repl_session_plugin_call_destroy_agmt_cb - Aborted - No replication area\n");
            return;
        }
        (*thefunc)(agmt_get_priv(ra), replarea);
        slapi_sdn_free(&replarea);
    }

    return;
}
Beispiel #23
0
int
value_dn_normalize_value(Slapi_Value *value)
{
	Slapi_DN *sdn = NULL;
	int rc = 0;

	if (NULL == value) {
		return rc;
	}

	sdn = slapi_sdn_new_dn_passin(value->bv.bv_val);
	if (slapi_sdn_get_dn(sdn)) {
		value->bv.bv_val = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
		value->bv.bv_len = slapi_sdn_get_ndn_len(sdn);
		slapi_sdn_free(&sdn);
		slapi_value_set_flags(value, SLAPI_ATTR_FLAG_NORMALIZED_CES);
	} else {
		rc = 1;
		slapi_ch_free((void **)&sdn); /* free just Slapi_DN */
	}

	return rc;
}
Beispiel #24
0
static int
_ger_g_permission_granted (
	Slapi_PBlock *pb,
	Slapi_Entry *e,
	const char *subjectdn,
	char **errbuf
	)
{
	char *proxydn = NULL;
	Slapi_DN *requestor_sdn, *entry_sdn;
	char *errtext = NULL;
	int isroot;
	int rc;

	/*
	 * Theorically, we should check if the entry has "g"
	 * permission granted to the requestor. If granted,
	 * allows the effective rights on that entry and its
	 * attributes within the entry to be returned for
	 * ANY subject.
	 *
	 * "G" permission granting has not been implemented yet,
	 * the current release assumes that "g" permission be 
	 * granted to root and owner of any entry.
	 */

	/*
	 * The requestor may be either the bind dn or a proxy dn
	 */
	if ((proxyauth_get_dn( pb, &proxydn, &errtext ) == LDAP_SUCCESS) && ( proxydn != NULL ))
	{
		requestor_sdn = slapi_sdn_new_dn_passin ( proxydn );
	}
	else
	{
		slapi_ch_free_string(&proxydn); /* this could still have been set - free it */
		requestor_sdn = &(pb->pb_op->o_sdn);
	}
	if ( slapi_sdn_get_dn (requestor_sdn) == NULL )
	{
		slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"_ger_g_permission_granted - Anonymous has no g permission\n" );
		rc = LDAP_INSUFFICIENT_ACCESS;
		goto bailout;
	}
	isroot = slapi_dn_isroot ( slapi_sdn_get_dn (requestor_sdn) );
	if ( isroot )
	{
		/* Root has "g" permission on any entry */
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	entry_sdn = slapi_entry_get_sdn ( e );
	if ( entry_sdn == NULL || slapi_sdn_get_dn (entry_sdn) == NULL )
	{
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	if ( slapi_sdn_compare ( requestor_sdn, entry_sdn ) == 0 )
	{
		/* Owner has "g" permission on his own entry */
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	/* if the requestor and the subject user are identical, let's grant it */
	if ( strcasecmp ( slapi_sdn_get_ndn(requestor_sdn), subjectdn ) == 0)
	{
		/* Requestor should see his own permission rights on any entry */
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"_ger_g_permission_granted - %s\n", *errbuf);
	rc = LDAP_INSUFFICIENT_ACCESS;

bailout:
	if ( proxydn )
	{
		/* The ownership of proxydn has passed to requestor_sdn */ 
		slapi_sdn_free ( &requestor_sdn );
	}
	return rc;
}
Beispiel #25
0
int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
                      struct ipapwd_krbcfg **config, int check_flags)
{
    int ret, ssf;
    int rc = LDAP_SUCCESS;
    Slapi_Backend *be;
    const Slapi_DN *psdn;
    Slapi_DN *sdn;
    char *dn = NULL;

    LOG_TRACE("=>\n");

#ifdef LDAP_EXTOP_PASSMOD_CONN_SECURE
    if (check_flags & IPAPWD_CHECK_CONN_SECURE) {
       /* Allow password modify on all connections with a Security Strength
        * Factor (SSF) higher than 1 */
        if (slapi_pblock_get(pb, SLAPI_OPERATION_SSF, &ssf) != 0) {
            LOG("Could not get SSF from connection\n");
            *errMesg = "Operation requires a secure connection.\n";
            rc = LDAP_OPERATIONS_ERROR;
            goto done;
        }

        if (ssf <= 1) {
            *errMesg = "Operation requires a secure connection.\n";
            rc = LDAP_CONFIDENTIALITY_REQUIRED;
            goto done;
        }
    }
#endif

    if (check_flags & IPAPWD_CHECK_DN) {
        /* check we have a valid DN in the pblock or just abort */
        ret = slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
        if (ret) {
            LOG("Tried to change password for an invalid DN [%s]\n",
                dn ? dn : "<NULL>");
            *errMesg = "Invalid DN";
            rc = LDAP_OPERATIONS_ERROR;
            goto done;
        }
        sdn = slapi_sdn_new_dn_byref(dn);
        if (!sdn) {
            LOG_FATAL("Unable to convert dn to sdn %s", dn ? dn : "<NULL>");
            *errMesg = "Internal Error";
            rc = LDAP_OPERATIONS_ERROR;
            goto done;
        }
        be = slapi_be_select(sdn);
        slapi_sdn_free(&sdn);

        psdn = slapi_be_getsuffix(be, 0);
        if (!psdn) {
            *errMesg = "Invalid DN";
            rc = LDAP_OPERATIONS_ERROR;
            goto done;
        }
    }

    /* get the kerberos context and master key */
    *config = ipapwd_getConfig();
    if (NULL == *config) {
        LOG_FATAL("Error Retrieving Master Key");
        *errMesg = "Fatal Internal Error";
        rc = LDAP_OPERATIONS_ERROR;
    }

done:
    return rc;
}
Beispiel #26
0
/*
  Given an entry, provide the account policy in effect for that entry.
  Returns non-0 if function fails.  If account policy comes back NULL, it's
  not an error; the entry is simply not covered by a policy.
*/
int
get_acctpolicy( Slapi_PBlock *pb, Slapi_Entry *target_entry, void *plugin_id,
                acctPolicy **policy )
{
    Slapi_DN *sdn = NULL;
    Slapi_Entry *policy_entry = NULL;
    Slapi_Attr *attr;
    Slapi_Value *sval = NULL;
    int ldrc;
    char *attr_name;
    char *policy_dn = NULL;
    acctPluginCfg *cfg;
    int rc = 0;

    if( policy == NULL ) {
        /* Bad parameter */
        return( -1 );
    }

    *policy = NULL;

    config_rd_lock();
    cfg = get_config();
    /* Return success and NULL policy */
    policy_dn = get_attr_string_val( target_entry, cfg->spec_attr_name );
    if( policy_dn == NULL ) {
        slapi_log_err(SLAPI_LOG_PLUGIN, PLUGIN_NAME,
                      "get_acctpolicy - \"%s\" is not governed by an account inactivity "
                      "policy subentry\n", slapi_entry_get_ndn( target_entry ) );
        if (cfg->inactivitylimit != ULONG_MAX) {
            goto dopolicy;
        }
        slapi_log_err(SLAPI_LOG_PLUGIN, PLUGIN_NAME,
                      "get_acctpolicy - \"%s\" is not governed by an account inactivity "
                      "global policy\n", slapi_entry_get_ndn( target_entry ) );
        config_unlock();
        return rc;
    }

    sdn = slapi_sdn_new_dn_byref( policy_dn );
    ldrc = slapi_search_internal_get_entry( sdn, NULL, &policy_entry,
                                            plugin_id );
    slapi_sdn_free( &sdn );

    /* There should be a policy but it can't be retrieved; fatal error */
    if( policy_entry == NULL ) {
        if( ldrc != LDAP_NO_SUCH_OBJECT ) {
            slapi_log_err(SLAPI_LOG_ERR, PLUGIN_NAME,
                          "get_acctpolicy - Error retrieving policy entry \"%s\": %d\n", policy_dn, ldrc );
        } else {
            slapi_log_err(SLAPI_LOG_PLUGIN, PLUGIN_NAME,
                          "get_acctpolicy - Policy entry \"%s\" is missing: %d\n", policy_dn, ldrc );
        }
        rc = -1;
        goto done;
    }

dopolicy:
    *policy = (acctPolicy *)slapi_ch_calloc( 1, sizeof( acctPolicy ) );

    if ( !policy_entry ) { /* global policy */
        (*policy)->inactivitylimit = cfg->inactivitylimit;
        goto done;
    }

    for( slapi_entry_first_attr( policy_entry, &attr ); attr != NULL;
            slapi_entry_next_attr( policy_entry, attr, &attr ) ) {
        slapi_attr_get_type(attr, &attr_name);
        if( !strcasecmp( attr_name, cfg->limit_attr_name ) ) {
            if( slapi_attr_first_value( attr, &sval ) == 0 ) {
                (*policy)->inactivitylimit = slapi_value_get_ulong( sval );
            }
        }
    }
done:
    config_unlock();
    slapi_ch_free_string( &policy_dn );
    slapi_entry_free( policy_entry );
    return( rc );
}
Beispiel #27
0
int
aclinit_main()
{
	Slapi_PBlock		*pb;
	int					rv;
	Slapi_DN			*sdn;
	void 				*node;

	if (acl_initialized) {
		/* There is no need to do anything more */
		return 0;
	}

	/* Initialize the LIBACCESS ACL library */
	if (ACL_Init() != 0) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			 "aclinit_main - ACL Library Initialization failed\n");
		return 1;
	}
	
	/* register all the LASes supported by the DS */
	if (ACL_ERR == __aclinit__RegisterLases()) {
		/* Error is already logged */
		return 1;
	}

	/* Register all the Attrs */
	if (ACL_ERR == __aclinit__RegisterAttributes()) {
		/* Error is already logged */
		return 1;
	}

	/*
	 * Register to get backend state changes so we can add/remove
	 * acis from backends that come up and go down.
	*/

	slapi_register_backend_state_change((void *) NULL, acl_be_state_change_fnc);
	

	/* register the extensions */
	/* ONREPL Moved to the acl_init function because extensions
       need to be registered before any operations are issued
    if  ( 0 != acl_init_ext() ) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"Unable to initialize the extensions\n");
		return 1;
	} */

	/* create the mutex array */
	if ( 0 != aclext_alloc_lockarray ( ) ) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"aclinit_main - Unable to create the mutext array\n");
		return 1;
	}

    /* Allocate the pool */
	if ( 0 != acl_create_aclpb_pool () ) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"aclinit_main - Unable to create the acl private pool\n");
		return 1;
	}

	/*
	 * Now read all the ACLs from all the backends and put it
	 * in a list
	 */
	/* initialize the ACLLIST sub-system */
	if ( 0 != (rv = acllist_init ( ))) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"aclinit_main - Unable to initialize the plugin:%d\n", rv );
		return 1;
	}

	/* Initialize the anonymous profile i.e., generate it */
	rv = aclanom_init ();

	pb = slapi_pblock_new();
	
	/*
	 * search for the aci_attr_type attributes of all entries.
	 *
	 * slapi_get_fist_suffix() and slapi_get_next_suffix() do not return the 
	 * rootdse entry so we search for acis in there explicitly here.
	*/

	sdn = slapi_sdn_new_ndn_byval("");
	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"aclinit_main - Searching for all acis(scope base) at suffix ''\n");
	aclinit_search_and_update_aci ( 0,		/* thisbeonly */
										sdn,	/* base */
										NULL,	/* be name*/
										LDAP_SCOPE_BASE, ACL_ADD_ACIS,
										DO_TAKE_ACLCACHE_WRITELOCK);
	slapi_sdn_free(&sdn);	

	sdn = slapi_get_first_suffix( &node, 1 );
	while (sdn)
	{
		slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"aclinit_main - Searching for all acis(scope subtree) at suffix '%s'\n", 
					slapi_sdn_get_dn(sdn) );
		aclinit_search_and_update_aci ( 0,		/* thisbeonly */
										sdn,	/* base */
										NULL,	/* be name*/
										LDAP_SCOPE_SUBTREE, ACL_ADD_ACIS,
										DO_TAKE_ACLCACHE_WRITELOCK);
		sdn = slapi_get_next_suffix( &node, 1 );
	}

	/* Initialize it. */
	acl_initialized = 1;

	/* generate the signatures */
	acl_set_aclsignature ( aclutil_gen_signature ( 100 ) );

	/* Initialize the user-group cache */
	rv = aclgroup_init ( );

	aclanom_gen_anomProfile (DO_TAKE_ACLCACHE_READLOCK);

	/* Register both of the proxied authorization controls (version 1 and 2) */
	slapi_register_supported_control( LDAP_CONTROL_PROXYAUTH,
			SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
			| SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
			| SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
			| SLAPI_OPERATION_EXTENDED );
	slapi_register_supported_control( LDAP_CONTROL_PROXIEDAUTH,
			SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
			| SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
			| SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
			| SLAPI_OPERATION_EXTENDED );

	slapi_pblock_destroy ( pb );
	return 0;
}
Beispiel #28
0
void
referint_thread_func(void *arg)
{
    PRFileDesc *prfd;
    char **plugin_argv = (char **)arg;
    char *logfilename;
    char thisline[MAX_LINE];
    char delimiter[]="\t\n";
    char *ptoken;
    char *tmprdn;
    char *iter = NULL;
    Slapi_DN *sdn = NULL;
    Slapi_DN *tmpsuperior = NULL;
    int logChanges = 0;
    int delay;
    int no_changes;

    if(plugin_argv == NULL){
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
            "referint_thread_func not get args \n" );
        return;
    }

    delay = atoi(plugin_argv[0]);
    logfilename = plugin_argv[1]; 
    logChanges = atoi(plugin_argv[2]);
    /*
     * keep running this thread until plugin is signaled to close
     */
    while(1){ 
        no_changes=1;
        while(no_changes){
            PR_Lock(keeprunning_mutex);
            if(keeprunning == 0){
                PR_Unlock(keeprunning_mutex);
                break;
            }
            PR_Unlock(keeprunning_mutex);

            referint_lock();
            if (( prfd = PR_Open( logfilename, PR_RDONLY, REFERINT_DEFAULT_FILE_MODE )) == NULL ){
                referint_unlock();
                /* go back to sleep and wait for this file */
                PR_Lock(keeprunning_mutex);
                PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
                PR_Unlock(keeprunning_mutex);
            } else {
                no_changes = 0;
            }
        }
        /*
         *  Check keep running here, because after break out of no
         *  changes loop on shutdown, also need to break out of this
         *  loop before trying to do the changes. The server
         *  will pick them up on next startup as file still exists
         */
        PR_Lock(keeprunning_mutex);
        if(keeprunning == 0){
            PR_Unlock(keeprunning_mutex);
            break;
        }
        PR_Unlock(keeprunning_mutex);  

        while( GetNextLine(thisline, MAX_LINE, prfd) ){
            ptoken = ldap_utf8strtok_r(thisline, delimiter, &iter);
            sdn = slapi_sdn_new_normdn_byref(ptoken);
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);

            if(!strcasecmp(ptoken, "NULL")) {
                tmprdn = NULL;
            } else {
                tmprdn = slapi_ch_smprintf("%s", ptoken);
            }

            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
            if (!strcasecmp(ptoken, "NULL")) {
                tmpsuperior = NULL;
            } else {
                tmpsuperior = slapi_sdn_new_normdn_byref(ptoken);
            }
            ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter);
            if (strcasecmp(ptoken, "NULL") != 0) {
                /* Set the bind DN in the thread data */
                if(slapi_td_set_dn(slapi_ch_strdup(ptoken))){
                    slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to set thread data\n");
                }
            }

            update_integrity(plugin_argv, sdn, tmprdn, tmpsuperior, logChanges);

            slapi_sdn_free(&sdn);
            slapi_ch_free_string(&tmprdn);
            slapi_sdn_free(&tmpsuperior);
        }

        PR_Close(prfd);

        /* remove the original file */
        if( PR_SUCCESS != PR_Delete(logfilename) ){
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                "referint_postop_close could not delete \"%s\"\n", logfilename );
        }

        /* unlock and let other writers back at the file */
        referint_unlock();

        /* wait on condition here */
        PR_Lock(keeprunning_mutex);
        PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
        PR_Unlock(keeprunning_mutex);
    }

    /* cleanup resources allocated in start  */
    if (NULL != keeprunning_mutex) {
        PR_DestroyLock(keeprunning_mutex);
    }
    if (NULL != referint_mutex) {
        PR_DestroyLock(referint_mutex);
    }
    if (NULL != keeprunning_cv) {
        PR_DestroyCondVar(keeprunning_cv);
    }
}
Beispiel #29
0
/*
 * 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);
	}
}
Beispiel #30
0
/* This function is called to process operation that come over external connections */
void
do_modrdn( Slapi_PBlock *pb )
{
	Slapi_Operation *operation;
	BerElement	*ber;
	char		*rawdn = NULL, *rawnewsuperior = NULL;
	const char	*dn = NULL, *newsuperior = NULL;
	char		*newrdn = NULL;
	int		err = 0, deloldrdn = 0;
	ber_len_t	len = 0;
	char		*newdn = NULL;
	char		*parent = NULL;
	Slapi_DN	sdn;
	Slapi_DN	snewdn;
	Slapi_DN	*snewsuperior = NULL;

	LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );

	/* count the modrdn request */
	slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps);

	slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
	ber = operation->o_ber;

	slapi_sdn_init(&sdn);
	slapi_sdn_init(&snewdn);

	/*
	 * Parse the modrdn request.  It looks like this:
	 *
	 *	ModifyRDNRequest := SEQUENCE {
	 *		entry		    DistinguishedName,
	 *		newrdn		    RelativeDistinguishedName,
	 *		deleteoldrdn	    BOOLEAN,
	 *		newSuperior	[0] LDAPDN OPTIONAL -- v3 only
	 *	}
	 */

	if (ber_scanf(ber, "{aab", &rawdn, &newrdn, &deloldrdn) == LBER_ERROR) {
		LDAPDebug( LDAP_DEBUG_ANY,
		    "ber_scanf failed (op=ModRDN; params=DN,newRDN,deleteOldRDN)\n",
		    0, 0, 0 );
		op_shared_log_error_access (pb, "MODRDN", "???", "decoding error");
		send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
		    "unable to decode DN, newRDN, or deleteOldRDN parameters",
		    0, NULL );
        goto free_and_return;
	}

	if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) {
		/* This "len" is not used... */
		if ( pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) {
			LDAPDebug( LDAP_DEBUG_ANY,
			    "got newSuperior in LDAPv2 modrdn op\n", 0, 0, 0 );
			op_shared_log_error_access (pb, "MODRDN",
										rawdn?rawdn:"", "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
			    "received newSuperior in LDAPv2 modrdn", 0, NULL );
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			goto free_and_return;
		}
		if ( ber_scanf( ber, "a", &rawnewsuperior ) == LBER_ERROR ) {
			LDAPDebug( LDAP_DEBUG_ANY,
			    "ber_scanf failed (op=ModRDN; params=newSuperior)\n",
			    0, 0, 0 );
			op_shared_log_error_access (pb, "MODRDN", rawdn, "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
			    "unable to decode newSuperior parameter", 0, NULL );
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			goto free_and_return;
		}
	}

	/* Check if we should be performing strict validation. */
	if (config_get_dn_validate_strict()) {
		/* check that the dn is formatted correctly */
		err = slapi_dn_syntax_check(pb, rawdn, 1);
		if (err) { /* syntax check failed */
			op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"",
							"strict: invalid dn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
							 NULL, "invalid dn", 0, NULL);
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			slapi_ch_free_string( &rawnewsuperior );
			goto free_and_return;
		}
		/* check that the new rdn is formatted correctly */
		err = slapi_dn_syntax_check(pb, newrdn, 1);
		if (err) { /* syntax check failed */
			op_shared_log_error_access(pb, "MODRDN", newrdn?newrdn:"", 
							"strict: invalid new rdn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
							 NULL, "invalid new rdn", 0, NULL);
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			slapi_ch_free_string( &rawnewsuperior );
			goto free_and_return;
		}
	}
	slapi_sdn_init_dn_passin(&sdn, rawdn);
	dn = slapi_sdn_get_dn(&sdn);
	if (rawdn && (strlen(rawdn) > 0) && (NULL == dn)) {
		/* normalization failed */
		op_shared_log_error_access(pb, "MODRDN", rawdn, "invalid dn");
		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, 
		                 "invalid dn", 0, NULL);
		slapi_ch_free_string( &newrdn );
		slapi_ch_free_string( &rawnewsuperior );
		goto free_and_return;
	}

	if (rawnewsuperior) {
		if (config_get_dn_validate_strict()) {
			/* check that the dn is formatted correctly */
			err = slapi_dn_syntax_check(pb, rawnewsuperior, 1);
			if (err) { /* syntax check failed */
				op_shared_log_error_access(pb, "MODRDN", rawnewsuperior,
							"strict: invalid new superior");
				send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
								 NULL, "invalid new superior", 0, NULL);
				slapi_ch_free_string( &rawnewsuperior );
				goto free_and_return;
			}
		}
		snewsuperior = slapi_sdn_new_dn_passin(rawnewsuperior);
		newsuperior = slapi_sdn_get_dn(snewsuperior);
	}

	/*
	 * If newsuperior is myself or my descendent, the modrdn should fail.
	 * Note: need to check the case newrdn is given, and newsuperior
	 * uses the newrdn, as well.
	 */ 
	parent = slapi_dn_parent(slapi_sdn_get_ndn(&sdn));
	newdn = slapi_ch_smprintf("%s,%s", newrdn, parent);
	/* slapi_sdn_init_normdn_passin expects normalized but NOT
	 * decapitalized dn */
	slapi_sdn_init_dn_passin(&snewdn, newdn);
	if (0 == slapi_sdn_compare(&sdn, snewsuperior) ||
	    0 == slapi_sdn_compare(&snewdn, snewsuperior)) {
		op_shared_log_error_access(pb, "MODRDN", newsuperior,
						 "new superior is identical to the entry dn");
		send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
						 "new superior is identical to the entry dn", 0, NULL);
		goto free_and_return;
	}
	if (slapi_sdn_issuffix(snewsuperior, &sdn) ||
	    slapi_sdn_issuffix(snewsuperior, &snewdn)) {
		/* E.g.,
		 * newsuperior: ou=sub,ou=people,dc=example,dc=com
		 * dn: ou=people,dc=example,dc=com
		 */
		op_shared_log_error_access(pb, "MODRDN", newsuperior,
						 "new superior is descendent of the entry");
		send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
						 "new superior is descendent of the entry", 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, "MODRDN", dn, "failed to decode LDAP controls");
		send_ldap_result( pb, err, NULL, NULL, 0, NULL );
		goto free_and_return;
	}

	LDAPDebug( LDAP_DEBUG_ARGS,
			   "do_modrdn: dn (%s) newrdn (%s) deloldrdn (%d)\n", dn, newrdn,
			   deloldrdn );

	slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &pb->pb_op->o_isroot );
	/* dn, newrdn and newsuperior are all normalized */
	slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET,
	                  (void *)slapi_sdn_get_udn(&sdn) );
	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, (void *)snewsuperior );
	slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn );

	op_shared_rename(pb, 0 /* do not pass in ownership of string arguments */ );

free_and_return:
	slapi_sdn_done(&sdn);
	slapi_ch_free_string(&newrdn);
	slapi_sdn_free(&snewsuperior);
	slapi_sdn_done(&snewdn);
	slapi_ch_free_string(&parent);

	return;
}