예제 #1
0
int slapi_sdn_issuffix( const Slapi_DN *sdn, const Slapi_DN *suffix_sdn )
{
	slapi_sdn_get_ndn( sdn );
	slapi_sdn_get_ndn( suffix_sdn );

	return dnIsSuffix( &sdn->ndn, &suffix_sdn->ndn );
}
예제 #2
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;
}
예제 #3
0
int slapi_sdn_compare( const Slapi_DN *sdn1, const Slapi_DN *sdn2 )
{
	int match = -1;

	slapi_sdn_get_ndn( sdn1 );
	slapi_sdn_get_ndn( sdn2 );

	dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL,
		(struct berval *)&sdn1->ndn, (void *)&sdn2->ndn );

	return match;
}
예제 #4
0
파일: aclanom.c 프로젝트: Firstyear/ds
/*
 * This routine sets up a "context" for evaluation of access control
 * on a given entry for an anonymous user.
 * It just factors out the scope and targetfilter info into a list
 * of indices of the global anom profile list, that apply to this
 * entry, and stores them in the aclpb.
 * It's use relies on the way that access control is checked in the mailine search
 * code in the core server, namely: check filter, check entry, then check each
 * attribute.  So, we call this in acl_access_allowed() before calling
 * aclanom_match_profile()--therafter, aclanom_match_profile() uses the
 * context to evaluate access to the entry and attributes.
 * 
 * If there are no anom profiles, or the anom profiles get cancelled
 * due to complex anon acis, then that's OK, aclanom_match_profile()
 * returns -1 and the mainline acl code kicks in.
 *
 * The lifetime of this context info is the time it takes to check
 * access control for all parts of this entry (filter, entry, attributes).
 * So, if for an example an entry changes and a given anom profile entry
 * no longer applies, we will not notice until the next round of access
 * control checking on the entry--this is acceptable.
 * 
 * The gain on doing this factoring in the following type of search
 * was approx 6%:
 * anon bind, 20 threads, exact match, ~20 attributes returned, 
 * (searchrate & DirectoryMark).
 * 
*/
void
aclanom_get_suffix_info(Slapi_Entry *e,
							struct acl_pblock *aclpb ) {
	int i;
	char     *ndn = NULL;
	Slapi_DN    *e_sdn;
	const char    *aci_ndn;
	struct scoped_entry_anominfo *s_e_anominfo =
			&aclpb->aclpb_scoped_entry_anominfo;

	ANOM_LOCK_READ ();
		
	s_e_anominfo->anom_e_nummatched=0;

	ndn = slapi_entry_get_ndn ( e ) ;
	e_sdn= slapi_entry_get_sdn ( e ) ;
	for (i=acl_anom_profile->anom_numacls-1; i >= 0; i-- ) {
		aci_ndn = slapi_sdn_get_ndn (acl_anom_profile->anom_targetinfo[i].anom_target);
		if (!slapi_sdn_issuffix(e_sdn,acl_anom_profile->anom_targetinfo[i].anom_target)
				|| (!slapi_is_rootdse(ndn) && slapi_is_rootdse(aci_ndn)))
						continue;
		if ( acl_anom_profile->anom_targetinfo[i].anom_filter ) {
			if ( slapi_vattr_filter_test( aclpb->aclpb_pblock, e,
                               		acl_anom_profile->anom_targetinfo[i].anom_filter, 
					0 /*don't do acess chk*/)  != 0)
				continue;
		}
		s_e_anominfo->anom_e_targetInfo[s_e_anominfo->anom_e_nummatched]=i;
		s_e_anominfo->anom_e_nummatched++;
	}
	ANOM_UNLOCK_READ (); 
}
예제 #5
0
int slapi_sdn_isparent( const Slapi_DN *parent, const Slapi_DN *child )
{
	Slapi_DN child_parent;

	slapi_sdn_get_ndn( child );

	slapi_sdn_init( &child_parent );
	dnParent( (struct berval *)&child->ndn, &child_parent.ndn );

	return ( slapi_sdn_compare( parent, &child_parent ) == 0 );
}
예제 #6
0
/*
 * This is called on a master when a replication agreement is
 * destroyed.  Any cookie allocated when the agreement was initialized
 * should be free'd here.
 */
static void
test_repl_session_plugin_destroy_cb(void *cookie, const Slapi_DN *repl_subtree)
{
    slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
        "test_repl_session_plugin_destroy_cb() called for suffix \"%s\".\n",
        slapi_sdn_get_ndn(repl_subtree));

    /* free cookie */
    slapi_ch_free_string((char **)&cookie);

    return;
}
예제 #7
0
void slapi_sdn_get_backend_parent( const Slapi_DN *sdn,
	Slapi_DN *sdn_parent,
	const Slapi_Backend *backend )
{
	slapi_sdn_get_ndn( sdn );

	if ( backend == NULL ||
	     be_issuffix( (Slapi_Backend *)backend, (struct berval *)&sdn->ndn ) == 0 ) {
		slapi_sdn_get_parent( sdn, sdn_parent );
	}

}
예제 #8
0
/*
 * lookup instance names by suffix.
 * if isexact == 0: returns instances including ones that associates with
 *					its sub suffixes.
 *					e.g., suffix: "o=<suffix>" is given, these are returned:
 *						  suffixes: o=<suffix>, ou=<ou>,o=<suffix>, ...
 *						  instances: inst of "o=<suffix>",
 *									 inst of "ou=<ou>,o=<suffix>",
 *										...
 * if isexact != 0: returns an instance that associates with the given suffix
 *					e.g., suffix: "o=<suffix>" is given, these are returned:
 *						  suffixes: "o=<suffix>"
 *						  instances: inst of "o=<suffix>"
 * Note: if suffixes 
 */
int
slapi_lookup_instance_name_by_suffix(char *suffix,
							char ***suffixes, char ***instances, int isexact)
{
	Slapi_Backend *be = NULL;
	struct suffixlist *list;
	char *cookie = NULL;
	const char *thisdn;
	int thisdnlen;
	int suffixlen;
	int count;
	int i;
	int rval = -1;

	if (instances == NULL)
		return rval;

	PR_ASSERT(suffix);

	rval = 0;
	suffixlen = strlen(suffix);
	cookie = NULL;
	be = slapi_get_first_backend (&cookie);
	while (be) {
		if (NULL == be->be_suffixlist) {
			be = (backend *)slapi_get_next_backend (cookie);
			continue;
		}
		count = slapi_counter_get_value(be->be_suffixcounter);
		list = be->be_suffixlist;
		for (i = 0; list && i < count; i++) {
			thisdn = slapi_sdn_get_ndn(list->be_suffix);
			thisdnlen = slapi_sdn_get_ndn_len(list->be_suffix);
			if (isexact?suffixlen!=thisdnlen:suffixlen>thisdnlen){
				list = list->next;
				continue;
			}
			if (isexact?(!slapi_UTF8CASECMP(suffix, (char *)thisdn)):
				(!slapi_UTF8CASECMP(suffix,	(char *)thisdn+thisdnlen-suffixlen)))
			{
				charray_add(instances, slapi_ch_strdup(be->be_name));
				if (suffixes)
					charray_add(suffixes, slapi_ch_strdup(thisdn));
			}
			list = list->next;
		}
		be = (backend *)slapi_get_next_backend (cookie);
	}
	slapi_ch_free((void **)&cookie);
	
	return rval;
}
예제 #9
0
Slapi_ValueSet *
replica_updatedn_list_get_members(Slapi_DN *dn)
{
	static char* const filter_groups = "(|(objectclass=groupOfNames)(objectclass=groupOfUniqueNames)(objectclass=groupOfURLs))";
	static char* const	type_member = "member";
	static char* const	type_uniquemember = "uniquemember";
	static char* const	type_memberURL = "memberURL";

	int rval;
	char *attrs[4]; 
	Slapi_PBlock *mpb = slapi_pblock_new ();
	Slapi_ValueSet *members = slapi_valueset_new();
		
	attrs[0] = type_member;
	attrs[1] = type_uniquemember;
	attrs[2] = type_memberURL;
	attrs[3] = NULL;
	slapi_search_internal_set_pb (  mpb, slapi_sdn_get_ndn(dn), LDAP_SCOPE_BASE, filter_groups,
					&attrs[0], 0, NULL /* controls */, NULL /* uniqueid */,
					repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION), 0);
	slapi_search_internal_pb(mpb);
	slapi_pblock_get(mpb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
	if (rval == LDAP_SUCCESS) {
		Slapi_Entry	**ep;
		slapi_pblock_get(mpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &ep);
		if ((ep != NULL) && (ep[0] != NULL)) {
			Slapi_Attr *attr = NULL;
			Slapi_Attr *nextAttr = NULL;
			Slapi_ValueSet *vs = NULL;
			char *attrType;
			slapi_entry_first_attr ( ep[0],  &attr);
			while (attr) {
				slapi_attr_get_type ( attr, &attrType );

				if ((strcasecmp (attrType, type_member) == 0) ||
				    (strcasecmp (attrType, type_uniquemember) == 0 ))  {
					slapi_attr_get_valueset(attr, &vs);
					slapi_valueset_join_attr_valueset(attr, members, vs);
					slapi_valueset_free(vs);
				} else if (strcasecmp (attrType, type_memberURL) == 0) {
					/* not yet supported */
				}
				slapi_entry_next_attr ( ep[0], attr, &nextAttr );
				attr = nextAttr;
			}
		}
	}
	slapi_free_search_results_internal(mpb);
	slapi_pblock_destroy (mpb);
	return(members);
}
예제 #10
0
파일: pam_ptimpl.c 프로젝트: leto/389-ds
static char *
derive_from_bind_entry(Slapi_PBlock *pb, const Slapi_DN *bindsdn, 
                       MyStrBuf *pam_id, char *map_ident_attr, int *locked)
{
	Slapi_Entry *entry = NULL;
	char *attrs[] = { NULL, NULL };
	attrs[0] = map_ident_attr;
	int rc = slapi_search_internal_get_entry((Slapi_DN *)bindsdn, attrs, &entry,
											 pam_passthruauth_get_plugin_identity());

	if (rc != LDAP_SUCCESS) {
		slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
						"Could not find BIND dn %s (error %d - %s)\n",
						slapi_sdn_get_ndn(bindsdn), rc, ldap_err2string(rc));
		init_my_str_buf(pam_id, NULL);
   	} else if (NULL == entry) {
		slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
						"Could not find entry for BIND dn %s\n",
						slapi_sdn_get_ndn(bindsdn));
		init_my_str_buf(pam_id, NULL);
	} else if (slapi_check_account_lock( pb, entry, 0, 0, 0 ) == 1) {
		slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
						"Account %s inactivated.\n",
						slapi_sdn_get_ndn(bindsdn));
		init_my_str_buf(pam_id, NULL);
		*locked = 1;
	} else {
		char *val = slapi_entry_attr_get_charptr(entry, map_ident_attr);
		init_my_str_buf(pam_id, val);
		slapi_ch_free_string(&val);
	}

	slapi_entry_free(entry);

	return pam_id->str;
}
예제 #11
0
int slapi_sdn_isgrandparent( const Slapi_DN *parent, const Slapi_DN *child )
{
	Slapi_DN child_grandparent;

	slapi_sdn_get_ndn( child );

	slapi_sdn_init( &child_grandparent );
	dnParent( (struct berval *)&child->ndn, &child_grandparent.ndn );
	if ( child_grandparent.ndn.bv_len == 0 ) {
		return 0;
	}

	dnParent( &child_grandparent.ndn, &child_grandparent.ndn );

	return ( slapi_sdn_compare( parent, &child_grandparent ) == 0 );
}
예제 #12
0
PRBool
replica_updatedn_list_ismember(ReplicaUpdateDNList list, const Slapi_DN *dn)
{
	PLHashTable *hash = list;
	PRBool ret = PR_FALSE;

	const char *ndn = slapi_sdn_get_ndn(dn);

	/* Bug 605169 - null ndn would cause core dump */
	if ( ndn ) {
		if ((uintptr_t)PL_HashTableLookupConst(hash, ndn))
                    ret = PR_TRUE;
                else
                    ret = PR_FALSE;
	}

	return ret;
}
예제 #13
0
/*
 * This is called on a master when a replication agreement is
 * initialized at startup.  A cookie can be allocated at this
 * time which is passed to other callbacks on the master side.
 */
static void *
test_repl_session_plugin_agmt_init_cb(const Slapi_DN *repl_subtree)
{
    char *cookie = NULL;

    slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
        "test_repl_session_plugin_init_cb() called for suffix \"%s\".\n",
        slapi_sdn_get_ndn(repl_subtree));

    /* allocate a string and set as the cookie */
    cookie = slapi_ch_smprintf("cookie test");

    slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
        "test_repl_session_plugin_init_cb(): Setting cookie: \"%s\".\n",
        cookie);

    return cookie;
}
예제 #14
0
/*
 * This is called on a master when it receives a reply to a
 * start replication extop that we sent to a replica.  Any
 * extra data sent by a replication session callback on the
 * replica will be set here as the data parameter.  The data_guid
 * should be checked first to ensure that the sending side is
 * using the same replication session plug-in before making any
 * assumptions about the contents of the data parameter.  You
 * should not free data_guid or data.  The replication plug-in
 * will take care of freeing this memory.
 *
 * Returning non-0 will abort the replication session.  This
 * results in the master going into incremental backoff mode.
 */
static int
test_repl_session_plugin_post_acquire_cb(void *cookie, const Slapi_DN *repl_subtree, int is_total,
                                         const char *data_guid, const struct berval *data)
{
    int rc = 0;

    slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
        "test_repl_session_plugin_post_acquire_cb() called for suffix \"%s\", "
        "is_total: \"%s\" cookie: \"%s\".\n", slapi_sdn_get_ndn(repl_subtree),
        is_total ? "TRUE" : "FALSE", cookie ? (char *)cookie : "NULL");

    /* log any extra data that was sent from the replica */
    if (data_guid && data) {
        slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
            "test_repl_session_plugin_post_acquire_cb() received data: guid: \"%s\" data: \"%s\".\n",
            data_guid, data->bv_val);
    }

    return rc;
}
예제 #15
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;
}
예제 #16
0
/*
 * This is called on a master when we are about to acquire a
 * replica.  This callback can allocate some extra data to
 * be sent to the replica in the start replication request.
 * This memory will be free'd by the replication plug-in
 * after it is sent.  A guid string must be set that is to
 * be used by the receiving side to ensure that the data is
 * from the same replication session plug-in.
 *
 * Returning non-0 will abort the replication session.  This
 * results in the master going into incremental backoff mode.
 */
static int
test_repl_session_plugin_pre_acquire_cb(void *cookie, const Slapi_DN *repl_subtree,
                                        int is_total, char **data_guid, struct berval **data)
{
    int rc = 0;

    slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
        "test_repl_session_plugin_pre_acquire_cb() called for suffix \"%s\", "
        "is_total: \"%s\", cookie: \"%s\".\n", slapi_sdn_get_ndn(repl_subtree),
        is_total ? "TRUE" : "FALSE", cookie ? (char *)cookie : "NULL");

    /* allocate some data to be sent to the replica */
    *data_guid = slapi_ch_smprintf("test-guid");
    *data = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
    (*data)->bv_val = slapi_ch_smprintf("test-data");
    (*data)->bv_len = strlen((*data)->bv_val) + 1;

    slapi_log_err(SLAPI_LOG_DEBUG, test_repl_session_plugin_name,
        "test_repl_session_plugin_pre_acquire_cb() sending data: guid: \"%s\" data: \"%s\".\n",
	*data_guid, (*data)->bv_val);

    return rc;
}
예제 #17
0
파일: aclanom.c 프로젝트: Firstyear/ds
/*
 * aclanom_match_profile
 *	Look at the anonymous profile and see if we can use it or not.
 *
 *
 *	Inputs:
 *		Slapi_Pblock			- The Pblock
 *		Slapi_Entry *e			- The entry for which we are asking permission.
 *		char *attr			- Attribute name
 *		int  access			- access type
 *
 *	Return:
 *		LDAP_SUCCESS ( 0 )		- acess is allowed.
 *		LDAP_INSUFFICIENT_ACCESS (50 )  - access denied.
 *		-1			        - didn't match the targets
 *
 * Assumptions:
 * 	The caller of this module has to make sure that the client is 
 *	an anonymous client.
 */
int
aclanom_match_profile (Slapi_PBlock *pb, struct acl_pblock *aclpb, Slapi_Entry *e,
						char *attr, int access ) 
{

	struct	anom_profile	*a_profile;
	int						result, i, k;
	char					**destArray;
	int						tmatched = 0;
	int						loglevel;
	struct scoped_entry_anominfo *s_e_anominfo =
			&aclpb->aclpb_scoped_entry_anominfo;

	loglevel = slapi_is_loglevel_set(SLAPI_LOG_ACL) ? SLAPI_LOG_ACL : SLAPI_LOG_ACLSUMMARY;

	/* WE are only interested for READ/SEARCH  */
	if (  !(access & ( SLAPI_ACL_SEARCH | SLAPI_ACL_READ)) )
		return -1;

	/* If we are here means, the client is doing a anonymous read/search */
	if ((a_profile = acl_anom_profile) == NULL ) {
		return -1;
	}		

	ANOM_LOCK_READ ();
	/* Check the signature first */
	if ( a_profile->anom_signature != acl_get_aclsignature () ) {
		/* Need to regenrate the signature.
	 	 * Need a WRITE lock to generate the anom profile  -
	 	 * which is obtained in acl__gen_anom_user_profile (). Since
	 	 * I don't have upgrade lock -- I have to do this way.
	 	 */
		ANOM_UNLOCK_READ ();
		aclanom_gen_anomProfile (DO_TAKE_ACLCACHE_READLOCK);
		aclanom_get_suffix_info(e, aclpb );
		ANOM_LOCK_READ ();
	}

	/* doing this early saves use a malloc/free/normalize cost */
	if ( !a_profile->anom_numacls ) {
		ANOM_UNLOCK_READ ();
		return -1;
	}

	result = LDAP_INSUFFICIENT_ACCESS;

	for ( k=0; k<s_e_anominfo->anom_e_nummatched; k++ ) {
		short	matched = 0;
		short	j = 0;	
	
		i = s_e_anominfo->anom_e_targetInfo[k];
	
		/* Check for right */
		if ( !(a_profile->anom_targetinfo[i].anom_access & access) )
			continue;
		
		/*
		 * XXX rbyrne Don't really understand the role of this
		 * but not causing any obvious bugs...get back to it.
		*/		
		tmatched++;
		
		if ( attr == NULL ) {
			result = LDAP_SUCCESS;
			break;
		}

		destArray = a_profile->anom_targetinfo[i].anom_targetAttrs;
		while ( destArray[j] ) {
			if ( strcasecmp ( destArray[j], "*") == 0 ||
				slapi_attr_type_cmp ( attr, destArray[j], 1 ) == 0 ) {
				matched = 1;
				break;
			}
			j++;
		}
		
		if ( a_profile->anom_targetinfo[i].anom_type  & ACI_TARGET_ATTR_NOT )
			result = matched ? LDAP_INSUFFICIENT_ACCESS : LDAP_SUCCESS;
		else 
			result = matched ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
	
		if ( result == LDAP_SUCCESS )
			break;
	} /* for */

	if ( slapi_is_loglevel_set(loglevel) ) {
		char					*ndn = NULL;
		Slapi_Operation			*op = NULL;
		PRUint64 o_connid = 0xffffffffffffffff; /* no op */
		int o_opid = -1; /* no op */
 
		ndn = slapi_entry_get_ndn ( e ) ;
		slapi_pblock_get(pb, SLAPI_OPERATION, &op);
		if (op) {
			o_connid = op->o_connid;
			o_opid = op->o_opid;
		}

		if ( result == LDAP_SUCCESS) {
			const char				*aci_ndn;
			aci_ndn = slapi_sdn_get_ndn (acl_anom_profile->anom_targetinfo[i].anom_target);
			if (access & SLAPI_ACL_MODDN) {
				slapi_log_err(loglevel, plugin_name, 
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) (from %s) to anonymous: acidn=\"%s\"\n",
					o_connid, o_opid,
					ndn,
					attr ? attr:"NULL",
					aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL",
					aci_ndn);
				
			} else {
				slapi_log_err(loglevel, plugin_name, 
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) to anonymous: acidn=\"%s\"\n",
					o_connid, o_opid,
					ndn,
					attr ? attr:"NULL",
					aci_ndn);
			}
		} else {
			if (access & SLAPI_ACL_MODDN) {
				slapi_log_err(loglevel, plugin_name,
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) (from %s) to anonymous\n",
					o_connid, o_opid,
					ndn, attr ? attr:"NULL" ,
					aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL");
			} else {
				slapi_log_err(loglevel, plugin_name,
					"aclanom_match_profile - conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) to anonymous\n",
					o_connid, o_opid,
					ndn, attr ? attr:"NULL" );
			}
		}
	}

	ANOM_UNLOCK_READ ();
	if ( tmatched == 0) 
		return -1;
	else 
		return result;
}
예제 #18
0
파일: referint.c 프로젝트: ohamada/389ds
/*
 * update multiple attribute values per _do_modify
 */
static int
_update_all_per_mod(Slapi_DN *entrySDN,      /* DN of the searched entry */
                    Slapi_Attr *attr,        /* referred attribute */
                    char *attrName,
                    Slapi_DN *origDN,        /* original DN that was modified */
                    char *newRDN,            /* new RDN from modrdn */
                    const char *newsuperior, /* new superior from modrdn */
                    Slapi_PBlock *mod_pb)
{
    Slapi_Mods *smods = NULL;
    char *newDN = NULL;
    char **dnParts = NULL;
    char *sval = NULL;
    char *newvalue = NULL;
    char *p = NULL;
    size_t dnlen = 0;
    int rc = 0;
    int nval = 0;

    slapi_attr_get_numvalues(attr, &nval);

    if (NULL == newRDN && NULL == newsuperior) {
        /* in delete mode */
        LDAPMod *mods[2];
        char *values_del[2];
        LDAPMod attribute1;

        /* delete old dn so set that up */
        values_del[0] = (char *)slapi_sdn_get_dn(origDN);
        values_del[1] = NULL;
        attribute1.mod_type = attrName;
        attribute1.mod_op = LDAP_MOD_DELETE;
        attribute1.mod_values = values_del;
        mods[0] = &attribute1;
        /* terminate list of mods. */
        mods[1] = NULL;
        rc = _do_modify(mod_pb, entrySDN, mods);
        if (rc) {
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                "_update_all_per_mod: entry %s: deleting \"%s: %s\" failed (%d)"
                "\n", slapi_sdn_get_dn(entrySDN), attrName, slapi_sdn_get_dn(origDN), rc);
        }
    } else {
        /* in modrdn mode */
        const char *superior = NULL;
        int nval = 0;
        Slapi_Value *v = NULL;

        if (NULL == origDN) {
            slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "_update_all_per_mod: NULL dn was passed\n");
            goto bail;
        }
        /* need to put together rdn into a dn */
        dnParts = slapi_ldap_explode_dn( slapi_sdn_get_dn(origDN), 0 );
        if (NULL == dnParts) {
            slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "_update_all_per_mod: failed to explode dn %s\n",
                            slapi_sdn_get_dn(origDN));
            goto bail;
        }
        if (NULL == newRDN) {
            newRDN = dnParts[0];
        }
        if (newsuperior) {
            superior = newsuperior;
        } else {
            /* do not free superior */
            superior = slapi_dn_find_parent(slapi_sdn_get_dn(origDN));
        }
        /* newRDN and superior are already normalized. */
        newDN = slapi_ch_smprintf("%s,%s", newRDN, superior);
        slapi_dn_ignore_case(newDN);
        /* 
         * Compare the modified dn with the value of 
         * the target attribute of referint to find out
         * the modified dn is the ancestor (case 2) or
         * the value itself (case 1).
         *
         * E.g., 
         * (case 1) 
         * modrdn: uid=A,ou=B,o=C --> uid=A',ou=B',o=C
         *            (origDN)             (newDN)
         * member: uid=A,ou=B,ou=C --> uid=A',ou=B',ou=C
         *            (sval)               (newDN)
         *
         * (case 2) 
         * modrdn: ou=B,o=C --> ou=B',o=C
         *         (origDN)      (newDN)
         * member: uid=A,ou=B,ou=C --> uid=A,ou=B',ou=C
         *         (sval)              (sval' + newDN)
         */
        slapi_attr_get_numvalues(attr, &nval);
        smods = slapi_mods_new();
        slapi_mods_init(smods, 2 * nval + 1);

        for (nval = slapi_attr_first_value(attr, &v);
             nval != -1;
             nval = slapi_attr_next_value(attr, nval, &v)) {
            p = NULL;
            dnlen = 0;

            /* DN syntax, which should be a string */
            sval = slapi_ch_strdup(slapi_value_get_string(v));
            rc = slapi_dn_normalize_case_ext(sval, 0,  &p, &dnlen);
            if (rc == 0) { /* sval is passed in; not terminated */
                *(p + dnlen) = '\0';
                sval = p;
            } else if (rc > 0) {
                slapi_ch_free_string(&sval);
                sval = p;
            }
            /* else: (rc < 0) Ignore the DN normalization error for now. */

            p = PL_strstr(sval, slapi_sdn_get_ndn(origDN));
            if (p == sval) {
                /* (case 1) */
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
                slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newDN);

            } else if (p) {
                /* (case 2) */
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
                *p = '\0';
                newvalue = slapi_ch_smprintf("%s%s", sval, newDN);
                slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newvalue);
                slapi_ch_free_string(&newvalue);
            } 
            /* else: value does not include the modified DN.  Ignore it. */
            slapi_ch_free_string(&sval);
        }
        rc = _do_modify(mod_pb, entrySDN, slapi_mods_get_ldapmods_byref(smods));
        if (rc) {
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                        "_update_all_per_mod: entry %s failed (%d)\n",
                        slapi_sdn_get_dn(entrySDN), rc);
        }

        /* cleanup memory allocated for dnParts and newDN */
        if (dnParts){
            slapi_ldap_value_free(dnParts);
            dnParts = NULL;
        }
        slapi_ch_free_string(&newDN);
        slapi_mods_free(&smods);
    }

bail:
    return rc;
}
예제 #19
0
파일: modrdn.c 프로젝트: ohamada/389ds
/* 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;
}
예제 #20
0
int slapi_sdn_get_ndn_len( const Slapi_DN *sdn )
{
	slapi_sdn_get_ndn( sdn );

	return sdn->ndn.bv_len;
}
예제 #21
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;
}
예제 #22
0
파일: pam_ptconfig.c 프로젝트: Firstyear/ds
/*
 * Read and load configuration.  Validation will also
 * be performed unless skip_validate is set to non-0.
 * Returns PAM_PASSTHRU_SUCCESS if all is well.
 */
int
pam_passthru_load_config(int skip_validate)
{
    int status = PAM_PASSTHRU_SUCCESS;
    int result;
    int i;
    int alternate = 0;
    Slapi_PBlock *search_pb;
    Slapi_Entry **entries = NULL;

    slapi_log_err(SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
                     "=> pam_passthru_load_config\n");

    pam_passthru_write_lock();
    pam_passthru_delete_config();

    search_pb = slapi_pblock_new();

    /* Find all entries in the active config area. */
    slapi_search_internal_set_pb(search_pb, slapi_sdn_get_ndn(pam_passthru_get_config_area()),
                                 LDAP_SCOPE_SUBTREE, "objectclass=*",
                                 NULL, 0, NULL, NULL,
                                 pam_passthruauth_get_plugin_identity(), 0);
    slapi_search_internal_pb(search_pb);
    slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);

    if (LDAP_SUCCESS != result) {
        status = PAM_PASSTHRU_FAILURE;
        goto cleanup;
    }

    slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
                     &entries);
    if (NULL == entries || NULL == entries[0]) {
        status = PAM_PASSTHRU_FAILURE;
        goto cleanup;
    }

    /* Check if we are using an alternate config area.  We do this here
     * so we don't have to check each every time in the loop below. */
    if (slapi_sdn_compare(pam_passthru_get_config_area(),
            pam_passthruauth_get_plugin_sdn()) != 0) {
        alternate = 1;
    }

    /* Validate and apply config if valid.  If skip_validate is set, we skip
     * validation and just apply the config.  This should only be done if the
     * configuration has already been validated. */
    for (i = 0; (entries[i] != NULL); i++) {
        /* If this is the alternate config container, skip it since
         * we don't consider it to be an actual config entry. */
        if (alternate && (slapi_sdn_compare(pam_passthru_get_config_area(),
                slapi_entry_get_sdn(entries[i])) == 0)) {
            continue;
        }

        if (skip_validate || (PAM_PASSTHRU_SUCCESS == pam_passthru_validate_config(entries[i], NULL))) {
            if (PAM_PASSTHRU_FAILURE == pam_passthru_apply_config(entries[i])) {
                slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
                                 "pam_passthru_load_config - Unable to apply config "
                                 "for entry \"%s\"\n", slapi_entry_get_ndn(entries[i]));
            }
        } else {
            slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
                             "pam_passthru_load_config - Skipping invalid config "
                             "entry \"%s\"\n", slapi_entry_get_ndn(entries[i]));
        }
    }

  cleanup:
    slapi_free_search_results_internal(search_pb);
    slapi_pblock_destroy(search_pb);
    pam_passthru_unlock();
    slapi_log_err(SLAPI_LOG_TRACE, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
                    "<= pam_passthru_load_config\n");

    return status;
}