コード例 #1
0
ファイル: uid.c プロジェクト: ohamada/389ds
/*
 * 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;
}
コード例 #2
0
ファイル: ipa-winsync-config.c プロジェクト: AvidehST/freeipa
/*
 * 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;
}
コード例 #3
0
ファイル: common.c プロジェクト: LiptonB/freeipa
/* 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;
}
コード例 #4
0
ファイル: common.c プロジェクト: LiptonB/freeipa
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;
}
コード例 #5
0
ファイル: acct_util.c プロジェクト: Firstyear/ds
/*
  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 );
}
コード例 #6
0
ファイル: sync_refresh.c プロジェクト: Firstyear/ds
int
sync_read_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data)
{
	char *uniqueid = NULL;
	char *chgtype = NULL;
	char *chgnr = NULL;
	int chg_req;
	int prev = 0;
	int index = 0;
	unsigned long chgnum = 0;
	Sync_CallBackData *cb = (Sync_CallBackData *) cb_data;

	if (cb == NULL) {
		return(1);
	}

	uniqueid = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_UNIQUEID);
	if (uniqueid == NULL) {
		slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, 
			"sync_read_entry_from_changelog - Retro Changelog does not provide nsuniquedid."
			"Check RCL plugin configuration.\n" );
		return(1);
	}
	chgnr = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHANGENUMBER);
	chgnum = sync_number2ulong(chgnr);
	if (SYNC_INVALID_CHANGENUM == chgnum) {
		slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, 
			"sync_read_entry_from_changelog - Change number provided by Retro Changelog is invalid: %s\n", chgnr);
		slapi_ch_free_string(&chgnr);
		slapi_ch_free_string(&uniqueid);
		return(1);
	}
	if (chgnum < cb->change_start) {
		slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, 
			"sync_read_entry_from_changelog - "
			"Change number provided by Retro Changelog %s is less than the initial number %lu\n",
			chgnr, cb->change_start);
		slapi_ch_free_string(&chgnr);
		slapi_ch_free_string(&uniqueid);
		return(1);
	}
	index = chgnum - cb->change_start;
	chgtype = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_CHGTYPE);
	chg_req = sync_str2chgreq(chgtype);
	switch (chg_req){ 
		case LDAP_REQ_ADD:
			/* nsuniqueid cannot exist, just add reference */
			cb->cb_updates[index].upd_chgtype = LDAP_REQ_ADD;
			cb->cb_updates[index].upd_uuid = uniqueid;
			break;
		case LDAP_REQ_MODIFY:
			/* check if we have seen this uuid already */
			prev = sync_find_ref_by_uuid(cb->cb_updates, index, uniqueid);
			if (prev == -1) {
				cb->cb_updates[index].upd_chgtype = LDAP_REQ_MODIFY;
				cb->cb_updates[index].upd_uuid = uniqueid;
			} else {
				/* was add or mod, keep it */
				cb->cb_updates[index].upd_uuid = 0;
				cb->cb_updates[index].upd_chgtype = 0;
				slapi_ch_free_string(&uniqueid);
			}
			break;
		case LDAP_REQ_MODRDN:
			{
				/* if it is a modrdn, we finally need to decide if this will
				 * trigger a present or delete state, keep the info that
				 * the entry was subject to a modrdn
				 */
			int new_scope = 0;
			int old_scope = 0;
			Slapi_DN *original_dn;
			char *newsuperior = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_NEWSUPERIOR);
			char *entrydn = sync_get_attr_value_from_entry (cl_entry, CL_ATTR_ENTRYDN);
			/* if newsuperior is set we need to checkif the entry has been moved into
			 * or moved out of the scope of the synchronization request
			 */
			original_dn = slapi_sdn_new_dn_byref(entrydn);
			old_scope = sync_is_active_scope(original_dn,cb->orig_pb);
			slapi_sdn_free(&original_dn);
			slapi_ch_free_string(&entrydn);
			if (newsuperior) {
				Slapi_DN *newbase;
				newbase = slapi_sdn_new_dn_byref(newsuperior);
				new_scope = sync_is_active_scope(newbase, cb->orig_pb);
				slapi_ch_free_string(&newsuperior);
				slapi_sdn_free(&newbase);
			} else {
				/* scope didn't change */
				new_scope = old_scope;
			}
			prev = sync_find_ref_by_uuid(cb->cb_updates, index, uniqueid);
			if ( old_scope && new_scope ) {
				/* nothing changed, it's just a MOD */
				if (prev == -1) {
					cb->cb_updates[index].upd_chgtype = LDAP_REQ_MODIFY;
					cb->cb_updates[index].upd_uuid = uniqueid;
				} else {
					cb->cb_updates[index].upd_uuid = 0;
					cb->cb_updates[index].upd_chgtype = 0;
					slapi_ch_free_string(&uniqueid);
				}
			} else if ( old_scope ) {
				/* it was moved out of scope, handle as DEL */
				if (prev == -1) {
					cb->cb_updates[index].upd_chgtype = LDAP_REQ_DELETE;
					cb->cb_updates[index].upd_uuid = uniqueid;
					cb->cb_updates[index].upd_e = sync_deleted_entry_from_changelog(cl_entry);
				} else {
					cb->cb_updates[prev].upd_chgtype = LDAP_REQ_DELETE;
					cb->cb_updates[prev].upd_e = sync_deleted_entry_from_changelog(cl_entry);
					slapi_ch_free_string(&uniqueid);
				}
			} else if ( new_scope ) {
				/* moved into scope, handle as ADD */
					cb->cb_updates[index].upd_chgtype = LDAP_REQ_ADD;
					cb->cb_updates[index].upd_uuid = uniqueid;
			} else {
				/* nothing to do */
				slapi_ch_free_string(&uniqueid);
 			}
			slapi_sdn_free(&original_dn);
			break;
			}
		case LDAP_REQ_DELETE:
			/* check if we have seen this uuid already */
			prev = sync_find_ref_by_uuid(cb->cb_updates, index, uniqueid);
			if (prev == -1) {
				cb->cb_updates[index].upd_chgtype = LDAP_REQ_DELETE;
				cb->cb_updates[index].upd_uuid = uniqueid;
				cb->cb_updates[index].upd_e = sync_deleted_entry_from_changelog(cl_entry);
			} else {
				/* if it was added since last cookie state, we
				 * can ignoere it */				
				if (cb->cb_updates[prev].upd_chgtype == LDAP_REQ_ADD) {
					slapi_ch_free_string(&(cb->cb_updates[prev].upd_uuid));
					cb->cb_updates[prev].upd_uuid = NULL;
					cb->cb_updates[index].upd_uuid = NULL;
				} else {
					/* ignore previous mod */
					cb->cb_updates[index].upd_uuid = NULL;
					cb->cb_updates[prev].upd_chgtype = LDAP_REQ_DELETE;
					cb->cb_updates[prev].upd_e = sync_deleted_entry_from_changelog(cl_entry);
				}
				slapi_ch_free_string(&uniqueid);
			}
			break;
		default:
			slapi_ch_free_string(&uniqueid);
	}
	slapi_ch_free_string(&chgtype);
	slapi_ch_free_string(&chgnr);

	return (0);
}
コード例 #7
0
ファイル: psearch.c プロジェクト: leto/389-ds
/*
 * Check if there are any persistent searches.  If so,
 * the check to see if the chgtype is one of those the
 * client is interested in.  If so, then check to see if
 * the entry matches any of the filters the searches.
 * If so, then enqueue the entry on that persistent search's
 * ps_entryqueue and signal it to wake up and send the entry.
 *
 * Note that if eprev is NULL we assume that the entry's DN
 * was not changed by the op. that called this function.  If
 * chgnum is 0 it is unknown so we won't ever send it to a
 * client in the EntryChangeNotification control.
 */
void
ps_service_persistent_searches( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype,
	ber_int_t chgnum )
{
	LDAPControl *ctrl = NULL;
	PSearch	*ps = NULL;
	PSEQNode *pe = NULL;
	int  matched = 0;
	const char *edn;

	if ( !PS_IS_INITIALIZED()) {
		return;
	}

	if ( NULL == e ) {
		/* For now, some backends such as the chaining backend do not provide a post-op entry */
		return;
	}

	PSL_LOCK_READ();
	edn = slapi_entry_get_dn_const(e);

	for ( ps = psearch_list ? psearch_list->pl_head : NULL; NULL != ps; ps = ps->ps_next ) {
		char *origbase = NULL;
		Slapi_DN *base = NULL;
		Slapi_Filter	*f;
		int		scope;

		/* Skip the node that doesn't meet the changetype,
		 * or is unable to use the change in ps_send_results()
		 */
		if (( ps->ps_changetypes & chgtype ) == 0 ||
				ps->ps_pblock->pb_op == NULL ||
				slapi_op_abandoned( ps->ps_pblock ) ) {
			continue;
		}

		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d entry %s with chgtype %d "
						"matches the ps changetype %d\n",
						ps->ps_pblock->pb_conn->c_connid,
						ps->ps_pblock->pb_op->o_opid,
						edn, chgtype, ps->ps_changetypes);

		slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_FILTER, &f );
		slapi_pblock_get( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, &origbase );
		slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, &base );
		slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_SCOPE, &scope );
		if (NULL == base) {
			base = slapi_sdn_new_dn_byref(origbase);
			slapi_pblock_set(ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, base);
		}

		/*
		 * See if the entry meets the scope and filter criteria.
		 * We cannot do the acl check here as this thread
		 * would then potentially clash with the ps_send_results()
		 * thread on the aclpb in ps->ps_pblock.
		 * By avoiding the acl check in this thread, and leaving all the acl
		 * checking to the ps_send_results() thread we avoid
		 * the ps_pblock contention problem.
		 * The lesson here is "Do not give multiple threads arbitary access
		 * to the same pblock" this kind of muti-threaded access
		 * to the same pblock must be done carefully--there is currently no
		 * generic satisfactory way to do this.
		*/
		if ( slapi_sdn_scope_test( slapi_entry_get_sdn_const(e), base, scope ) &&
			 slapi_vattr_filter_test( ps->ps_pblock, e, f, 0 /* verify_access */ ) == 0 ) {
			PSEQNode *pOldtail;

			/* The scope and the filter match - enqueue it */

			matched++;
			pe = (PSEQNode *)slapi_ch_calloc( 1, sizeof( PSEQNode ));
			pe->pe_entry = slapi_entry_dup( e );
			if ( ps->ps_send_entchg_controls ) {
				/* create_entrychange_control() is more
				 * expensive than slapi_dup_control()
				 */
				if ( ctrl == NULL ) {
					int rc;
					rc = create_entrychange_control( chgtype, chgnum,
							eprev ? slapi_entry_get_dn_const(eprev) : NULL,
							&ctrl );
					if ( rc != LDAP_SUCCESS ) {
		   				LDAPDebug( LDAP_DEBUG_ANY, "ps_service_persistent_searches:"
						" unable to create EntryChangeNotification control for"
						" entry \"%s\" -- control won't be sent.\n",
						slapi_entry_get_dn_const(e), 0, 0 );
					}
				}
				if ( ctrl ) {
					pe->pe_ctrls[0] = slapi_dup_control( ctrl );
				}
			}

			/* Put it on the end of the list for this pers search */
			PR_Lock( ps->ps_lock );
			pOldtail = ps->ps_eq_tail;
			ps->ps_eq_tail = pe;
			if ( NULL == ps->ps_eq_head ) {
				ps->ps_eq_head = ps->ps_eq_tail;
			}
			else {
				pOldtail->pe_next = ps->ps_eq_tail;
			}
			PR_Unlock( ps->ps_lock );
		}
	}

   	PSL_UNLOCK_READ();

	/* Were there any matches? */
	if ( matched ) {
		ldap_control_free( ctrl );
		/* Turn 'em loose */
		ps_wakeup_all();
		LDAPDebug( LDAP_DEBUG_TRACE, "ps_service_persistent_searches: enqueued entry "
			"\"%s\" on %d persistent search lists\n", slapi_entry_get_dn_const(e), matched, 0 );
	} else {
		LDAPDebug( LDAP_DEBUG_TRACE, "ps_service_persistent_searches: entry "
			"\"%s\" not enqueued on any persistent search lists\n", slapi_entry_get_dn_const(e), 0, 0 );
	}

}