Exemplo n.º 1
0
/*
 * Parse the value from an LDAPv3 "Simple Paged Results" control.  They look
 * like this:
 * 
 *   realSearchControlValue ::= SEQUENCE {
 *   size INTEGER (0..maxInt),
 *   -- requested page size from client
 *   -- result set size estimate from server
 *   cookie OCTET STRING
 *   -- index for the pagedresults array in the connection
 *   }
 *
 * Return an LDAP error code (LDAP_SUCCESS if all goes well).
 */
int
pagedresults_parse_control_value( Slapi_PBlock *pb,
                                  struct berval *psbvp, ber_int_t *pagesize,
                                  int *index )
{
    int rc = LDAP_SUCCESS;
    struct berval cookie = {0};
    Connection *conn = pb->pb_conn;
    Operation *op = pb->pb_op;

    LDAPDebug0Args(LDAP_DEBUG_TRACE, "--> pagedresults_parse_control_value\n");
    if ( NULL == conn || NULL == op || NULL == pagesize || NULL == index ) {
        LDAPDebug1Arg(LDAP_DEBUG_ANY,
                      "<-- pagedresults_parse_control_value: %d\n",
                      LDAP_OPERATIONS_ERROR);
        return LDAP_OPERATIONS_ERROR;
    }
    *index = -1;

    if ( psbvp->bv_len == 0 || psbvp->bv_val == NULL )
    {
        rc = LDAP_PROTOCOL_ERROR;
    }
    else
    {
        BerElement *ber = ber_init( psbvp );
        if ( ber == NULL )
        {
            rc = LDAP_OPERATIONS_ERROR;
        }
        else
        {
            if ( ber_scanf( ber, "{io}", pagesize, &cookie ) == LBER_ERROR )
            {
                rc = LDAP_PROTOCOL_ERROR;
            }
            /* the ber encoding is no longer needed */
            ber_free(ber, 1);
            if ( cookie.bv_len <= 0 ) {
                int i;
                int maxlen;
                /* first time? */
                PR_Lock(conn->c_mutex);
                maxlen = conn->c_pagedresults.prl_maxlen;
                if (conn->c_pagedresults.prl_count == maxlen) {
                    if (0 == maxlen) { /* first time */
                        conn->c_pagedresults.prl_maxlen = 1;
                        conn->c_pagedresults.prl_list =
                            (PagedResults *)slapi_ch_calloc(1,
                                                        sizeof(PagedResults));
                    } else {
                        /* new max length */
                        conn->c_pagedresults.prl_maxlen *= 2;
                        conn->c_pagedresults.prl_list =
                            (PagedResults *)slapi_ch_realloc(
                                        (char *)conn->c_pagedresults.prl_list,
                                        sizeof(PagedResults) *
                                        conn->c_pagedresults.prl_maxlen);
                        /* initialze newly allocated area */
                        memset(conn->c_pagedresults.prl_list + maxlen, '\0',
                                   sizeof(PagedResults) * maxlen);
                    }
                    *index = maxlen; /* the first position in the new area */
                } else {
                    for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
                        if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
                            *index = i;
                            break;
                        }
                    }
                }
                conn->c_pagedresults.prl_count++;
                PR_Unlock(conn->c_mutex);
            } else {
                /* Repeated paged results request.
                 * PagedResults is already allocated. */
                char *ptr = slapi_ch_malloc(cookie.bv_len + 1);
                memcpy(ptr, cookie.bv_val, cookie.bv_len);
                *(ptr+cookie.bv_len) = '\0';
                *index = strtol(ptr, NULL, 10);
                slapi_ch_free_string(&ptr);
            }
            slapi_ch_free((void **)&cookie.bv_val);
        }
    }
    if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) {
        /* Need to keep the latest msgid to prepare for the abandon. */
        conn->c_pagedresults.prl_list[*index].pr_msgid = op->o_msgid;
    } else {
        rc = LDAP_PROTOCOL_ERROR;
        LDAPDebug1Arg(LDAP_DEBUG_ANY,
                      "pagedresults_parse_control_value: invalid cookie: %d\n",
                      *index);
    }

    LDAPDebug1Arg(LDAP_DEBUG_TRACE,
                  "<-- pagedresults_parse_control_value: idx %d\n", *index);
    return rc;
}
Exemplo n.º 2
0
void slapi_rdn_free( Slapi_RDN **rdn )
{
	slapi_rdn_done( *rdn );
	slapi_ch_free( (void **)rdn );
}
Exemplo n.º 3
0
static int
changelog4_create_be()
{
	int i, dir_count = 5;
    Slapi_Backend *rbe;
	slapi_be_config config;
	char *cl_dir = changelog4_get_dir ();
	char *cl_suffix;

    if ( cl_dir == NULL ) {
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, 
						"Error: no directory specified for changelog database.\n");
        return -1;
    }
	
	cl_suffix = changelog4_get_suffix ();

    if ( cl_suffix == NULL ) {
		slapi_ch_free ((void **)&cl_dir);
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, 
						"Error: no suffix specified for changelog database.\n");
        return -1;
    }

	/* setup configuration parameters for backend initialization */   
	config.type			= CHANGELOG_LDBM_TYPE;
	config.suffix		= cl_suffix;
	config.is_private	= 1;	/* yes */ 
	config.log_change	= 0;	/* no */
	config.directives = (slapi_config_directive*)slapi_ch_calloc(
                         dir_count, sizeof(slapi_config_directive));
    config.dir_count  = dir_count;

	for (i = 0; i < dir_count; i++)
	{
		config.directives[i].file_name = "(internal)";
		config.directives[i].lineno	= 0;	
	}

	/* setup indexes */
	config.directives[0].argv = NULL;
	config.directives[0].argc = 3;
	charray_add( &(config.directives[0].argv), slapi_ch_strdup( "index" ));
	charray_add( &(config.directives[0].argv), slapi_ch_strdup( attr_changenumber ));
	charray_add( &(config.directives[0].argv), slapi_ch_strdup( "eq" ));

    /* Set up the database directory */
    config.directives[1].argv = NULL;
    config.directives[1].argc = 2;
    charray_add( &(config.directives[1].argv), slapi_ch_strdup( "directory" ));
    charray_add( &(config.directives[1].argv), slapi_ch_strdup( cl_dir ));

    /* Override the entry cache size */
    config.directives[2].argv = NULL;
    config.directives[2].argc = 2;
    charray_add( &(config.directives[2].argv), slapi_ch_strdup( "cachesize" ));
    charray_add( &(config.directives[2].argv), slapi_ch_strdup( "10" ));

    /* Override the database cache size */
    config.directives[3].argv = NULL;
    config.directives[3].argc = 2;
    charray_add( &(config.directives[3].argv), slapi_ch_strdup( "dbcachesize" ));
    charray_add( &(config.directives[3].argv), slapi_ch_strdup( "1000000" ));
   
    /* Override the allids threshold */
    config.directives[4].argv = NULL;
    config.directives[4].argc = 2;
    charray_add( &(config.directives[4].argv), slapi_ch_strdup( "allidsthreshold" ));
	/* assumes sizeof(int) >= 32 bits */
    charray_add( &(config.directives[4].argv), slapi_ch_strdup( "2147483647" )); 

	/* rbe = slapi_be_create_instance(&config, LDBM_TYPE); */
	rbe= NULL;

	/* free memory allocated to argv */
	for (i = 0; i < dir_count; i++)
	{
		charray_free (config.directives[i].argv);
	}

	slapi_ch_free ((void **)&config.directives);
	slapi_ch_free ((void **)&cl_dir);
	slapi_ch_free ((void **)&cl_suffix);
 
	if (rbe == NULL)
	{
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, 
						"Error: failed to create changelog backend. "
						"Replication disabled.\n");
		return -1;
	}

    set_repl_backend (rbe);

	changelog4_init_trimming ();

	return 0;   
}
Exemplo n.º 4
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[SLAPI_DSE_RETURNTEXT_SIZE];
	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_err(SLAPI_LOG_ARGS, "op_shared_rename", 
				 "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_err(SLAPI_LOG_ARGS, "op_shared_rename", 
				 "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)
	{
		slapi_log_err(SLAPI_LOG_ARGS, "op_shared_rename",
			"Syntax check of newSuperior failed\n");
		if (!internal_op) {
			slapi_log_err(SLAPI_LOG_ARGS, "op_shared_rename",
				 "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_err(SLAPI_LOG_ARGS, "op_shared_rename",
				 "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) 
	{
		slapi_log_err(SLAPI_LOG_ARGS, "op_shared_rename", "do_moddn: newsuperior (%s)\n", newsuperior);
	}

	/* 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. */
	errorbuf[0] = '\0';
	if ((err = slapi_mapping_tree_select_and_check(pb, newdn, &be, &referral, errorbuf, sizeof(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) == SLAPI_PLUGIN_SUCCESS)
	{
		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 {
				/* Should we also be doing a disk space check here? */
				if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT))
				{ 
					write_auditfail_log_entry(pb); /* Record the operation in the audit log */
				}
			}
		}
		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);
	}
}
Exemplo n.º 5
0
static void
delete_bitwise_match_cb(struct bitwise_match_cb *bmc)
{
    slapi_ch_free_string(&bmc->type);
    slapi_ch_free((void **)&bmc);
}
Exemplo n.º 6
0
Arquivo: uid.c Projeto: ohamada/389ds
static int
search_one_berval(Slapi_DN *baseDN, const char *attrName,
		const struct berval *value, const char *requiredObjectClass,
		Slapi_DN *target)
{
	int result;
    char *filter;
    Slapi_PBlock *spb;

	result = LDAP_SUCCESS;

	/* If no value, can't possibly be a conflict */
	if ( (struct berval *)NULL == value )
		return result;

    filter = 0;
    spb = 0;

    BEGIN
      int err;
      int sres;
      Slapi_Entry **entries;
      static char *attrs[] = { "1.1", 0 };

      /* Create the filter - this needs to be freed */
      filter = create_filter(attrName, value, requiredObjectClass);

#ifdef DEBUG
      slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
        "SEARCH filter=%s\n", filter);
#endif

      /* Perform the search using the new internal API */
      spb = slapi_pblock_new();
      if (!spb) { result = uid_op_error(2); break; }

      slapi_search_internal_set_pb_ext(spb, baseDN, LDAP_SCOPE_SUBTREE,
      	filter, attrs, 0 /* attrs only */, NULL, NULL, plugin_identity, 0 /* actions */);
      slapi_search_internal_pb(spb);

      err = slapi_pblock_get(spb, SLAPI_PLUGIN_INTOP_RESULT, &sres);
      if (err) { result = uid_op_error(3); break; }
    
      /* Allow search to report that there is nothing in the subtree */
      if (sres == LDAP_NO_SUCH_OBJECT) break;

      /* Other errors are bad */
      if (sres) { result = uid_op_error(3); break; }

      err = slapi_pblock_get(spb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
              &entries);
      if (err) { result = uid_op_error(4); break; }

      /*
       * Look at entries returned.  Any entry found must be the
       * target entry or the constraint fails.
       */
      for(;*entries;entries++)
      {
#ifdef DEBUG
        slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
                        "SEARCH entry dn=%s\n", slapi_entry_get_dn(*entries));
#endif

        /*
         * It is a Constraint Violation if any entry is found, unless
         * the entry is the target entry (if any).
         */
        if (!target || slapi_sdn_compare(slapi_entry_get_sdn(*entries), target) != 0)
        {
          result = LDAP_CONSTRAINT_VIOLATION;
          break;
        }
      }

#ifdef DEBUG
      slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
        "SEARCH complete result=%d\n", result);
#endif
    END

    /* Clean-up */
    if (spb) {
	slapi_free_search_results_internal(spb);
	slapi_pblock_destroy(spb);
    }

    slapi_ch_free((void**)&filter);

  return result;
}
Exemplo n.º 7
0
void
slapi_int_connection_done_pb( Slapi_PBlock *pb )
{
	Connection		*conn;
	Operation		*op;

	PBLOCK_ASSERT_INTOP( pb, 0 );

	conn = pb->pb_conn;
	op = pb->pb_op;

	/* free allocated DNs */
	if ( !BER_BVISNULL( &op->o_dn ) )
		op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx );
	if ( !BER_BVISNULL( &op->o_ndn ) )
		op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx );

	if ( !BER_BVISNULL( &op->o_req_dn ) )
		op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	if ( !BER_BVISNULL( &op->o_req_ndn ) )
		op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );

	switch ( op->o_tag ) {
	case LDAP_REQ_MODRDN:
		if ( !BER_BVISNULL( &op->orr_newrdn ))
			op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
		if ( !BER_BVISNULL( &op->orr_nnewrdn ))
			op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
		if ( op->orr_newSup != NULL ) {
			assert( !BER_BVISNULL( op->orr_newSup ) );
			op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
			op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
		}
		if ( op->orr_nnewSup != NULL ) {
			assert( !BER_BVISNULL( op->orr_nnewSup ) );
			op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
			op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
		}
		slap_mods_free( op->orr_modlist, 1 );
		break;
	case LDAP_REQ_ADD:
		slap_mods_free( op->ora_modlist, 0 );
		break;
	case LDAP_REQ_MODIFY:
		slap_mods_free( op->orm_modlist, 1 );
		break;
	case LDAP_REQ_SEARCH:
		if ( op->ors_attrs != NULL ) {
			op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
			op->ors_attrs = NULL;
		}
		break;
	default:
		break;
	}

	slapi_ch_free_string( &conn->c_authmech.bv_val );
	slapi_ch_free_string( &conn->c_dn.bv_val );
	slapi_ch_free_string( &conn->c_ndn.bv_val );
	slapi_ch_free_string( &conn->c_peer_domain.bv_val );
	slapi_ch_free_string( &conn->c_peer_name.bv_val );

	if ( conn->c_sb != NULL ) {
		ber_sockbuf_free( conn->c_sb );
	}

	slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op );
	slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, conn );

	slapi_ch_free( (void **)&pb->pb_op->o_callback );
	slapi_ch_free( (void **)&pb->pb_op );
	slapi_ch_free( (void **)&pb->pb_conn );
	slapi_ch_free( (void **)&pb->pb_rs );
}
Exemplo n.º 8
0
Arquivo: init.c Projeto: Firstyear/ds
int 
ldbm_back_init( Slapi_PBlock *pb )
{
	struct ldbminfo	*li;
	int		rc;
	struct slapdplugin *p;
	static int interface_published = 0;

	slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_init", "=>\n");

   	slapi_pblock_get(pb, SLAPI_PLUGIN, &p);
	
	/* allocate backend-specific stuff */
	li = (struct ldbminfo *) slapi_ch_calloc( 1, sizeof(struct ldbminfo) );
	
	/* Record the identity of the ldbm plugin.  The plugin 
	 * identity is used during internal ops. */
	slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &(li->li_identity));

	/* keep a pointer back to the plugin */
	li->li_plugin = p;
	
	/* set shutdown flag to zero.*/
	li->li_shutdown = 0;

	/* Initialize the set of instances. */
	li->li_instance_set = objset_new(&ldbm_back_instance_set_destructor);
	
	/* initialize dblayer  */
	if (dblayer_init(li)) {
		slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "dblayer_init failed\n");
		goto fail;
	}

	/* Fill in the fields of the ldbminfo and the dblayer_private
	 * structures with some default values */
	ldbm_config_setup_default(li);

        /* ask the factory to give us space in the Connection object
         * (only bulk import uses this)
         */
        if (slapi_register_object_extension(p->plg_name, SLAPI_EXT_CONNECTION,
            factory_constructor, factory_destructor,
            &li->li_bulk_import_object, &li->li_bulk_import_handle) != 0) {
            slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init",
                      "slapi_register_object_extension failed.\n");
            goto fail;
        }

	/* add some private attributes */
	rc = ldbm_back_add_schema( pb );

	/* set plugin private pointer and initialize locks, etc. */
	rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) li );
	
	if ((li->li_dbcache_mutex = PR_NewLock()) == NULL ) {
            slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "PR_NewLock failed\n");
            goto fail;
        }

	if ((li->li_shutdown_mutex = PR_NewLock()) == NULL ) {
            slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "PR_NewLock failed\n");
            goto fail;
        }

	if ((li->li_config_mutex = PR_NewLock()) == NULL ) {
            slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "PR_NewLock failed\n");
            goto fail;
        }

	if ((li->li_dbcache_cv = PR_NewCondVar( li->li_dbcache_mutex )) == NULL ) {
            slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "PR_NewCondVar failed\n");
            goto fail;
        }

	/* set all of the necessary database plugin callback functions */
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
	    (void *) SLAPI_PLUGIN_VERSION_03 );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
	    (void *)&pdesc );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_BIND_FN, 
	    (void *) ldbm_back_bind );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UNBIND_FN, 
	    (void *) ldbm_back_unbind );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SEARCH_FN, 
	    (void *) ldbm_back_search );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN,
	    (void *) ldbm_back_next_search_entry );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_EXT_FN,
	    (void *) ldbm_back_next_search_entry_ext );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_PREV_SEARCH_RESULTS_FN,
	    (void *) ldbm_back_prev_search_results );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ENTRY_RELEASE_FN,
	    (void *) ldbm_back_entry_release );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SEARCH_RESULTS_RELEASE_FN,
	    (void *) ldbm_back_search_results_release );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_COMPARE_FN, 
	    (void *) ldbm_back_compare );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_MODIFY_FN, 
	    (void *) ldbm_back_modify );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_MODRDN_FN, 
	    (void *) ldbm_back_modrdn );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_FN, 
	    (void *) ldbm_back_add );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DELETE_FN, 
	    (void *) ldbm_back_delete );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ABANDON_FN, 
	    (void *) ldbm_back_abandon );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, 
	    (void *) ldbm_back_close );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_CLEANUP_FN, 
	    (void *) ldbm_back_cleanup );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_FLUSH_FN, 
	    (void *) ldbm_back_flush );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, 
	    (void *) ldbm_back_start );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SEQ_FN, 
	    (void *) ldbm_back_seq );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_RMDB_FN,
	    (void *) ldbm_back_rmdb );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_LDIF2DB_FN,
	    (void *) ldbm_back_ldif2ldbm );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DB2LDIF_FN,
	    (void *) ldbm_back_ldbm2ldif );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DB2INDEX_FN,
	    (void *) ldbm_back_ldbm2index );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ARCHIVE2DB_FN,
	    (void *) ldbm_back_archive2ldbm );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DB2ARCHIVE_FN,
	    (void *) ldbm_back_ldbm2archive );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UPGRADEDB_FN,
	    (void *) ldbm_back_upgradedb );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_UPGRADEDNFORMAT_FN,
	    (void *) ldbm_back_upgradednformat );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_DBVERIFY_FN,
	    (void *) ldbm_back_dbverify );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_BEGIN_FN,
	    (void *) dblayer_plugin_begin );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_COMMIT_FN,
	    (void *) dblayer_plugin_commit );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ABORT_FN,
	    (void *) dblayer_plugin_abort );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SIZE_FN,
	    (void *) ldbm_db_size );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_INIT_INSTANCE_FN,
	    (void *) ldbm_back_init ); /* register itself so that the secon instance
                                          can be initialized */
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_WIRE_IMPORT_FN,
	    (void *) ldbm_back_wire_import );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_SCHEMA_FN,
	    (void *) ldbm_back_add_schema );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_GET_INFO_FN,
	    (void *) ldbm_back_get_info );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_SET_INFO_FN,
	    (void *) ldbm_back_set_info );
	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_CTRL_INFO_FN,
	    (void *) ldbm_back_ctrl_info );

	if ( rc != 0 ) {
		slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "Failed %d\n", rc);
		goto fail;
	}
	
	/* register the IDL interface with the API broker */
	if(!interface_published)
	{
		IDL_api[0] = 0;
		IDL_api[1] = (void *)idl_alloc;
		IDL_api[2] = (void *)idl_insert;

		if( slapi_apib_register(IDL_v1_0_GUID, IDL_api) )
		{
			slapi_log_err(SLAPI_LOG_CRIT, "ldbm_back_init", "Failed to publish IDL interface\n");
			goto fail;
		}

		interface_published = 1;
	}

	slapi_log_err(SLAPI_LOG_TRACE, "ldbm_back_init", "<=\n");

	return( 0 );

fail:
	dblayer_terminate( li );
	slapi_ch_free((void **)&li);
	slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, NULL );
	return( -1 );
}
Exemplo n.º 9
0
/* Modify the Password attributes of the entry */
int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
                       struct ipapwd_data *data, int is_krb)
{
    int ret = 0;
    Slapi_Mods *smods = NULL;
    Slapi_Value **svals = NULL;
    Slapi_Value **ntvals = NULL;
    Slapi_Value **pwvals = NULL;
    char *nt = NULL;
    int is_smb = 0;
    int is_ipant = 0;
    int is_host = 0;
    Slapi_Value *sambaSamAccount;
    Slapi_Value *ipaNTUserAttrs;
    Slapi_Value *ipaHost;
    char *errMesg = NULL;
    char *modtime = NULL;

    LOG_TRACE("=>\n");

    sambaSamAccount = slapi_value_new_string("sambaSamAccount");
    if (slapi_entry_attr_has_syntax_value(data->target,
                                          "objectClass", sambaSamAccount)) {
        is_smb = 1;
    }
    slapi_value_free(&sambaSamAccount);

    ipaNTUserAttrs = slapi_value_new_string("ipaNTUserAttrs");
    if (slapi_entry_attr_has_syntax_value(data->target,
                                          "objectClass", ipaNTUserAttrs)) {
        is_ipant = 1;
    }
    slapi_value_free(&ipaNTUserAttrs);

    ipaHost = slapi_value_new_string("ipaHost");
    if (slapi_entry_attr_has_syntax_value(data->target,
                                          "objectClass", ipaHost)) {
        is_host = 1;
    }
    slapi_value_free(&ipaHost);

    ret = ipapwd_gen_hashes(krbcfg, data,
                            data->password,
                            is_krb, is_smb, is_ipant,
                            &svals, &nt, &ntvals, &errMesg);
    if (ret) {
        goto free_and_return;
    }

    smods = slapi_mods_new();

    if (svals) {
        slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
                                  "krbPrincipalKey", svals);

		/* krbLastPwdChange is used to tell whether a host entry has a
		 * keytab so don't set it on hosts.
		 */
        if (!is_host) {
	    /* change Last Password Change field with the current date */
            ret = ipapwd_setdate(data->target, smods, "krbLastPwdChange",
                                 data->timeNow, false);
            if (ret != LDAP_SUCCESS)
                goto free_and_return;

	    /* set Password Expiration date */
            ret = ipapwd_setdate(data->target, smods, "krbPasswordExpiration",
                                 data->expireTime, (data->expireTime == 0));
            if (ret != LDAP_SUCCESS)
                goto free_and_return;
	}
    }

    if (nt && is_smb) {
        slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                              "sambaNTPassword", nt);
    }

    if (ntvals && is_ipant) {
        slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
                                  "ipaNTHash", ntvals);
    }

    if (is_smb) {
        /* with samba integration we need to also set sambaPwdLastSet or
         * samba will decide the user has to change the password again */
        if (data->changetype == IPA_CHANGETYPE_ADMIN) {
            /* if it is an admin change instead we need to let know to
             * samba as well that the use rmust change its password */
            modtime = slapi_ch_smprintf("0");
        } else {
            modtime = slapi_ch_smprintf("%ld", (long)data->timeNow);
        }
        if (!modtime) {
            LOG_FATAL("failed to smprintf string!\n");
            ret = LDAP_OPERATIONS_ERROR;
            goto free_and_return;
        }
        slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                              "sambaPwdLastset", modtime);
    }
    if (is_krb) {
        if (data->changetype == IPA_CHANGETYPE_ADMIN) {
            slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                                 "krbLoginFailedCount", "0");
        }
    }
    /* let DS encode the password itself, this allows also other plugins to
     * intercept it to perform operations like synchronization with Active
     * Directory domains through the replication plugin */
    slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
                          "userPassword", data->password);

    /* set password history */
    if (data->policy.history_length > 0) {
        pwvals = ipapwd_setPasswordHistory(smods, data);
        if (pwvals) {
            slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
                                      "passwordHistory", pwvals);
        }
    }

    /* FIXME:
     * instead of replace we should use a delete/add so that we are
     * completely sure nobody else modified the entry meanwhile and
     * fail if that's the case */

    /* commit changes */
    ret = ipapwd_apply_mods(data->dn, smods);

    LOG_TRACE("<= result: %d\n", ret);

free_and_return:
    if (nt) slapi_ch_free((void **)&nt);
    if (modtime) slapi_ch_free((void **)&modtime);
    slapi_mods_free(&smods);
    ipapwd_free_slapi_value_array(&svals);
    ipapwd_free_slapi_value_array(&ntvals);
    ipapwd_free_slapi_value_array(&pwvals);

    return ret;
}
Exemplo n.º 10
0
/* just like slapi_ch_free, but the argument is the address of a string
   This helps with compile time error checking
*/
void
slapi_ch_free_string(char **s)
{
	slapi_ch_free((void **)s);
}
Exemplo n.º 11
0
/*
 * Create or update an AVL tree of values that can be used to speed up value
 *	lookups.  We store the index keys for the values in the AVL tree so
 *	we can use a trivial comparison function.
 *
 * Returns:
 *  LDAP_SUCCESS on success,
 *  LDAP_TYPE_OR_VALUE_EXISTS if the value already exists,
 *  LDAP_OPERATIONS_ERROR for some unexpected failure.
 *
 * Sets *valuetreep to the root of the AVL tree that was created.  If a
 *	non-zero value is returned, the tree is freed if free_on_error is non-zero
 *  and *valuetreep is set to NULL.
 */
int
valuetree_add_valuearray( const Slapi_Attr *sattr, Slapi_Value **va, Avlnode **valuetreep, int *duplicate_index )
{
	int rc= LDAP_SUCCESS;

	PR_ASSERT(sattr!=NULL);
	PR_ASSERT(valuetreep!=NULL);

	if ( duplicate_index ) {
		*duplicate_index = -1;
	}

	if ( !valuearray_isempty(va) )
	{
		Slapi_Value	**keyvals;
		/* Convert the value array into key values */
		if ( slapi_attr_values2keys_sv( sattr, (Slapi_Value**)va, &keyvals, LDAP_FILTER_EQUALITY ) != 0 ) /* jcm cast */
		{
			LDAPDebug( LDAP_DEBUG_ANY,"slapi_attr_values2keys_sv for attribute %s failed\n", sattr->a_type, 0, 0 );
			rc= LDAP_OPERATIONS_ERROR;
		}
		else
		{
			int	i;
			valuetree_node *vaip;
			for ( i = 0; rc==LDAP_SUCCESS && va[i] != NULL; ++i )
			{
				if ( keyvals[i] == NULL )
				{
					LDAPDebug( LDAP_DEBUG_ANY,"slapi_attr_values2keys_sv for attribute %s did not return enough key values\n", sattr->a_type, 0, 0 );
					rc= LDAP_OPERATIONS_ERROR;
				}
				else
				{
					vaip = (valuetree_node *)slapi_ch_malloc( sizeof( valuetree_node ));
					vaip->index = i;
					vaip->sval = keyvals[i];
					if (( rc = avl_insert( valuetreep, vaip, valuetree_node_cmp, valuetree_dupvalue_disallow )) != 0 )
					{
						slapi_ch_free( (void **)&vaip );
						/* Value must already be in there */
						rc= LDAP_TYPE_OR_VALUE_EXISTS;
						if ( duplicate_index ) {
							*duplicate_index = i;
						}
					}
					else
					{
						keyvals[i]= NULL;
					}
				}
			}
			/* start freeing at index i - the rest of them have already
			   been moved into valuetreep
			   the loop iteration will always do the +1, so we have
			   to remove it if so */
			i = (i > 0) ? i-1 : 0;
			valuearray_free_ext( &keyvals, i );
		}
	}
	if(rc!=0)
	{
		valuetree_free( valuetreep );
	}

	return rc;
}
Exemplo n.º 12
0
/*
 * Common function that is called by aclplugin_preop_search() and
 * aclplugin_preop_modify().
 *
 * Return values:
 *	0 - all is well; proceed.
 *  1 - fatal error; result has been sent to client.
 */ 
int
aclplugin_preop_common( Slapi_PBlock *pb )
{
	char		*proxy_dn = NULL;	/* id being assumed */
	char		*dn;		/* proxy master */
	char		*errtext = NULL;
	int			lderr;
	Acl_PBlock	*aclpb;

	TNF_PROBE_0_DEBUG(aclplugin_preop_common_start ,"ACL","");

	aclpb = acl_get_aclpb ( pb, ACLPB_BINDDN_PBLOCK );

	if (aclpb == NULL) {
		slapi_log_err(SLAPI_LOG_ACL, plugin_name, "aclplugin_preop_common - Error: aclpb is NULL\n" );
		slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL );
		return 1;
	}

        /* See if we have initialized already */
        if ( aclpb->aclpb_state & ACLPB_INITIALIZED ) goto done;

	/*
	 * The following mallocs memory for proxy_dn, but not the dn.
	 * The proxy_dn is the id being assumed, while dn
	 * is the "proxy master".
	*/
	if ( LDAP_SUCCESS != ( lderr = proxyauth_get_dn( pb, &proxy_dn, &errtext ))) {
		/*
		 * Fatal error -- send a result to the client and arrange to skip
		 * any further processing.
		 */
		slapi_send_ldap_result( pb, lderr, NULL, errtext, 0, NULL );
		TNF_PROBE_1_DEBUG(aclplugin_preop_common_end ,"ACL","",
						tnf_string,proxid_error,"");
		slapi_ch_free_string(&proxy_dn);
		return 1;	/* skip any further processing */
	}
	slapi_pblock_get ( pb, SLAPI_REQUESTOR_DN, &dn );


	/*
	 * The dn is copied into the aclpb during initialization.
	*/
	if ( proxy_dn) {
		TNF_PROBE_0_DEBUG(proxyacpb_init_start,"ACL","");

		slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"aclplugin_preop_common - Proxied authorization dn is (%s)\n", proxy_dn );
		acl_init_aclpb ( pb, aclpb, proxy_dn, 1 );
		aclpb = acl_new_proxy_aclpb ( pb );
		acl_init_aclpb ( pb, aclpb, dn, 0 );
		slapi_ch_free ( (void **) &proxy_dn );
		
		TNF_PROBE_0_DEBUG(proxyacpb_init_end,"ACL","");
 
	} else {
		TNF_PROBE_0_DEBUG(aclpb_init_start,"ACL","");
		acl_init_aclpb ( pb, aclpb, dn, 1 );
		TNF_PROBE_0_DEBUG(aclpb_init_end,"ACL","");

	}

done:
	TNF_PROBE_0_DEBUG(aclplugin_preop_common_end ,"ACL","");

	return 0;
}
Exemplo n.º 13
0
int
collation_config (size_t cargc, char** cargv,
		  const char* fname, size_t lineno)
    /* Process one line from a configuration file.
       Return 0 if it's OK, -1 if it's not recognized.
       Any other return value is a process exit code.
    */
{
    if (cargc <= 0) { /* Bizarre.  Oh, well... */
    } else if (!strcasecmp (cargv[0], "NLS")) {
	/* ignore - not needed anymore with ICU - was used to get path for NLS_Initialize */
    } else if (!strcasecmp (cargv[0], "collation")) {
	if ( cargc < 7 ) {
	    slapi_log_err(SLAPI_LOG_ERR, COLLATE_PLUGIN_SUBSYSTEM,
		       "collation_config - %s: line %lu ignored: only %lu arguments (expected "
		       "collation language country variant strength decomposition oid ...)\n",
		       fname, (unsigned long)lineno, (unsigned long)cargc );
	} else {
	    auto size_t arg;
	    auto coll_profile_t* profile = (coll_profile_t*) slapi_ch_calloc (1, sizeof (coll_profile_t));
	    if (*cargv[1]) profile->language = slapi_ch_strdup (cargv[1]);
	    if (*cargv[2]) profile->country  = slapi_ch_strdup (cargv[2]);
	    if (*cargv[3]) profile->variant  = slapi_ch_strdup (cargv[3]);
	    switch (atoi(cargv[4])) {
	      case 1: profile->strength = UCOL_PRIMARY; break;
	      case 2: profile->strength = UCOL_SECONDARY; /* no break here? fall through? wtf? */
	      case 3: profile->strength = UCOL_TERTIARY; break;
	      case 4: profile->strength = UCOL_IDENTICAL; break;
	      default: profile->strength = UCOL_SECONDARY;
              slapi_log_err(SLAPI_LOG_ERR, COLLATE_PLUGIN_SUBSYSTEM,
                      "collation_config - %s: line %lu: strength \"%s\" not supported (will use 2)\n",
                      fname, (unsigned long)lineno, cargv[4]);
              break;
	    }
	    switch (atoi(cargv[5])) {
	      case 1: profile->decomposition = UCOL_OFF; break;
	      case 2: profile->decomposition = UCOL_DEFAULT; /* no break here? fall through? wtf? */
	      case 3: profile->decomposition = UCOL_ON; break;
	      default: profile->decomposition = UCOL_DEFAULT;
              slapi_log_err(SLAPI_LOG_ERR, COLLATE_PLUGIN_SUBSYSTEM,
                  "collation_config - %s: line %lu: decomposition \"%s\" not supported (will use 2)\n",
                  fname, (unsigned long)lineno, cargv[5]);
              break;
	    }

            {
                char descStr[256];
                char nameOrder[256];
                char nameSubstring[256];
                char oidString[256];
                char *tmpStr=NULL;
                Slapi_MatchingRuleEntry *mrentry=slapi_matchingrule_new();
 
                if(UCOL_PRIMARY == profile->strength) {
                    strcpy(nameOrder,"caseIgnoreOrderingMatch");
                    strcpy(nameSubstring,"caseIgnoreSubstringMatch");
                }
                else {
                    strcpy(nameOrder,"caseExactOrderingMatch");
                    strcpy(nameSubstring,"caseExactSubstringMatch");
                }

		/* PAR: this looks broken
                   the "extra" text based oids that are actually used
                   to form the name and description are always derived
                   from the language and country fields so there should
                   be no need to have two separate code paths to
                   set the name and description fields of the schema
                   as language is always available, and if country is
                   not, it is not in the name anyway.

                   Is it safe to assume all matching rules will follow
                   this convention?  The answer, or lack of it, probably
                   explains the reasoning for doing things the way they
                   are currently.
                */ 
                    
                if(cargc > 7) {
                    PL_strcatn(nameOrder,sizeof(nameOrder),"-");
                    PL_strcatn(nameOrder,sizeof(nameOrder),cargv[7]);
                    PL_strcatn(nameSubstring,sizeof(nameSubstring),"-");
                    PL_strcatn(nameSubstring,sizeof(nameSubstring),cargv[7]);
                    slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_NAME,
                                           (void *)slapi_ch_strdup(nameOrder));
                }
                else  {
                    if(0 != cargv[1][0]) {
                        PL_strcatn(nameOrder,sizeof(nameOrder),"-");
                        PL_strcatn(nameSubstring,sizeof(nameSubstring),"-");
                    } else {
						nameOrder[0] = 0;
						nameSubstring[0] = 0;
					}
                    PL_strcatn(nameOrder,sizeof(nameOrder),cargv[1]);
                    PL_strcatn(nameSubstring,sizeof(nameSubstring),cargv[1]);
                    slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_NAME,
                                           (void *)slapi_ch_strdup(nameOrder));
                }
                PL_strncpyz(oidString,cargv[6], sizeof(oidString));
                slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_OID,
                                       (void *)slapi_ch_strdup(oidString));
                if(0 != cargv[2][0]) {
                    PR_snprintf(descStr, sizeof(descStr), "%s-%s",cargv[1],cargv[2]);
                }
                else {
                    PL_strncpyz(descStr,cargv[1], sizeof(descStr));
                }
                slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_DESC,
						   (void *)slapi_ch_strdup(descStr));
                slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_SYNTAX,
						   (void *)slapi_ch_strdup(DIRSTRING_SYNTAX_OID));
                slapi_matchingrule_register(mrentry);
                slapi_matchingrule_get(mrentry,SLAPI_MATCHINGRULE_NAME,
                                       (void *)&tmpStr);
                slapi_ch_free((void **)&tmpStr);
                slapi_matchingrule_get(mrentry,SLAPI_MATCHINGRULE_OID,
                                       (void *)&tmpStr);
                slapi_ch_free((void **)&tmpStr);
                slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_NAME,
                                       (void *)slapi_ch_strdup(nameSubstring));
                PL_strcatn(oidString,sizeof(oidString),".6");
                slapi_matchingrule_set(mrentry,SLAPI_MATCHINGRULE_OID,
                                       (void *)slapi_ch_strdup(oidString));
                slapi_matchingrule_register(mrentry);
                slapi_matchingrule_free(&mrentry,1);
            }
 

	    for (arg = 6; arg < cargc; ++arg) {
		auto coll_id_t* id = (coll_id_t*) slapi_ch_malloc (sizeof (coll_id_t));
		id->oid     = slapi_ch_strdup (cargv[arg]);
		id->profile = profile;
		if (collation_ids <= 0) {
		    collation_id = (const coll_id_t**) slapi_ch_malloc (2 * sizeof (coll_id_t*));
		} else {
		    collation_id = (const coll_id_t**) slapi_ch_realloc
		      ((void*)collation_id, (collation_ids + 2) * sizeof (coll_id_t*));
		}
		collation_id [collation_ids++] = id;
		collation_id [collation_ids] = NULL;
	    }
	}
    } else {
	return -1; /* unrecognized */
    }
    return 0; /* success */
}
Exemplo n.º 14
0
indexer_t*
collation_indexer_create (const char* oid)
    /* Return a new indexer, based on the collation identified by oid.
       Return NULL if this can't be done.
    */
{
    indexer_t* ix = NULL;
    const coll_id_t** id = collation_id;
    char* locale = NULL; /* NULL == default locale */
    UCollator* coll = NULL;
    collation_indexer_t* etc = NULL;

    if (id) for (; *id; ++id) {
	if (!strcasecmp (oid, (*id)->oid)) {
	    const coll_profile_t* profile = (*id)->profile;
	    const int is_default = (profile->language == NULL && 
					 profile->country  == NULL && 
					 profile->variant  == NULL);
	    UErrorCode err = U_ZERO_ERROR;
	    if ( ! is_default) {
			err = s_newNamedLocaleFromComponents(&locale,
						     profile->language,
						     profile->country,
						     profile->variant);
	    }
	    if (err == U_ZERO_ERROR) {
		coll = ucol_open(locale, &err);
		/*
		 * If we found exactly the right collator for this locale,
		 * or if we found a fallback one, or if we are happy with
		 * the default, use it.
		 */
		if (U_SUCCESS(err)) {
		    etc = (collation_indexer_t*) slapi_ch_calloc (1, sizeof (collation_indexer_t));
		    ix = (indexer_t*) slapi_ch_calloc (1, sizeof (indexer_t));
		    ucol_setAttribute (coll, UCOL_STRENGTH, profile->strength, &err);
		    if (U_FAILURE(err)) {
		    	slapi_log_err(SLAPI_LOG_ERR, COLLATE_PLUGIN_SUBSYSTEM, "collation_indexer_create - "
		    	        "Could not set the collator strength for oid %s to %d: err %d\n",
				        oid, profile->strength, err);
		    }
		    ucol_setAttribute (coll, UCOL_DECOMPOSITION_MODE, profile->decomposition, &err);
		    if (U_FAILURE(err)) {
		    	slapi_log_err(SLAPI_LOG_ERR, COLLATE_PLUGIN_SUBSYSTEM, "collation_indexer_create - " 
		    		"Could not set the collator decomposition mode for oid %s to %d: err %d\n",
		    		oid, profile->decomposition, err);
		    }
		    etc->collator = coll;
		    for (id = collation_id; *id; ++id) {
		    	if ((*id)->profile == profile) {
		    		break; /* found the 'official' id */
		    	}
		    }
            if (!*id) {
                slapi_log_err(SLAPI_LOG_ERR, COLLATE_PLUGIN_SUBSYSTEM,
                        "collation_indexer_create - id not found\n");
                goto error;
            }

		    ix->ix_etc = etc;
		    ix->ix_oid = (*id)->oid;
		    ix->ix_index = collation_index;
		    ix->ix_destroy = collation_indexer_destroy;
		    break; /* return */
		    /* free (etc); */
		    /* free (ix); */
		} else if (err == U_USING_DEFAULT_WARNING) {
		    slapi_log_err(SLAPI_LOG_FILTER, COLLATE_PLUGIN_SUBSYSTEM,
		            "collation_indexer_create - Could not "
			        "create an indexer for OID %s for locale %s and could not "
			        "use default locale\n", oid, (locale ? locale : "(default)"));
		} else { /* error */
		    slapi_log_err(SLAPI_LOG_FILTER, COLLATE_PLUGIN_SUBSYSTEM,
		            "collation_indexer_create - Could not "
			        "create an indexer for OID %s for locale %s: err = %d\n",
			        oid, (locale ? locale : "(default)"), err);
		}
		if (coll) {
		    ucol_close (coll);
		    coll = NULL;
		}
	    }
	    break; /* failed to create the specified collator */
	}
    }
    goto done;
error:
    slapi_ch_free((void **)&etc);
    slapi_ch_free((void **)&ix);
    if (coll) {
        ucol_close (coll);
        coll = NULL;
    }
done:
    if (locale) {
	PR_smprintf_free(locale);
	locale = NULL;
    }
    return ix;
}
Exemplo n.º 15
0
int sync_srch_refresh_pre_search(Slapi_PBlock *pb)
{

	LDAPControl **requestcontrols;
	struct berval	*psbvp;
	Sync_Cookie *client_cookie = NULL;
	Sync_Cookie *session_cookie = NULL;
	int 	rc = 0;
	int sync_persist = 0;
	PRThread *tid = NULL;
	int entries_sent = 0;

	slapi_pblock_get (pb, SLAPI_REQCONTROLS, &requestcontrols);
	if ( slapi_control_present( requestcontrols, LDAP_CONTROL_SYNC, &psbvp, NULL )){
		char *cookie = NULL;
		int mode = 1;
		int refresh = 0;

		if ( sync_parse_control_value( psbvp, &mode,
									 &refresh, &cookie ) != LDAP_SUCCESS )
		{
			rc = 1;
			goto error_return;
		} else {
			/* control is valid, check if usere is allowed to perform sync searches */
			rc = sync_feature_allowed(pb);
			if (rc) {
				sync_result_err(pb,rc,NULL);
				goto error_return;
			}
		}

		if ( mode == 1 || mode == 3 )
		{

			/* we need to return a cookie in the result message
			 * indicating a state to be used in future sessions
			 * as starting point - create it now
			 */
			session_cookie = sync_cookie_create(pb);
			/*
			 *  if mode is persist we need to setup the persit handler
			 * to catch the mods while the refresh is done 
			 */
			if ( mode == 3 )
			{
				tid = sync_persist_add(pb);
				if ( tid ) 
					sync_persist = 1;
				else {
					rc = LDAP_UNWILLING_TO_PERFORM;
					sync_result_err(pb,rc,"Too many active synchronization sessions");
					goto error_return;
				}
			}
			/* 
			 * now handl the refresh request
			 * there are two scenarios
			 * 1. no cookie is provided this means send all entries matching the search request
			 * 2. a cookie is provided: send all entries changed since the cookie was issued
			 * 	-- return an error if the cookie is invalid
			 * 	-- return e-syncRefreshRequired if the data referenced in the cookie are no
			 * 		longer in the history
			*/
			if (cookie) {
				if ((client_cookie = sync_cookie_parse (cookie)) &&
				    sync_cookie_isvalid(client_cookie, session_cookie))
				{
					rc = sync_refresh_update_content(pb, client_cookie, session_cookie);
					if (rc == 0) 
						entries_sent = 1;
					if (sync_persist)
						rc = sync_intermediate_msg(pb, LDAP_TAG_SYNC_REFRESH_DELETE, session_cookie, NULL);
					else
						rc = sync_result_msg(pb, session_cookie);
				} else {
					rc = E_SYNC_REFRESH_REQUIRED;
					sync_result_err(pb,rc, "Invalid session cookie");
				}
			} else {
				rc = sync_refresh_initial_content (pb, sync_persist,  tid, session_cookie);
				if (rc == 0 && !sync_persist)
					/* maintained in postop code */
					session_cookie = NULL;
					/* if persis it will be handed over to persist code */
			}
			
			if ( rc ) {
				if (sync_persist)
					sync_persist_terminate (tid);
				goto error_return;
			} else if (sync_persist){
				Slapi_Operation *operation;

				slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
				if (client_cookie) {
					rc = sync_persist_startup(tid, session_cookie);
				}
				if (rc == 0) {
					session_cookie = NULL; /* maintained in persist code */
					slapi_operation_set_flag(operation, OP_FLAG_SYNC_PERSIST);
				}
			}
			

		} else {
			/* unknown mode, return an error */
			rc = 1;
		}
error_return:
	sync_cookie_free(&client_cookie);
	sync_cookie_free(&session_cookie);
	slapi_ch_free((void **)&cookie);
	}

	/* if we sent the entries
	 * return "error" to abort normal search
	 */ 
	if (  entries_sent > 0 ) {
		return(1);
	} else {
		return(rc);
	}
}
Exemplo n.º 16
0
/*
 * Thread routine for sending search results to a client
 * which is persistently waiting for them.
 *
 * This routine will terminate when either (a) the ps_complete
 * flag is set, or (b) the associated operation is abandoned.
 * In any case, the thread won't notice until it wakes from
 * sleeping on the ps_list condition variable, so it needs
 * to be awakened.
 */
static void
ps_send_results( void *arg )
{
    PSearch *ps = (PSearch *)arg;
	PSEQNode *peq, *peqnext;
	struct slapi_filter *filter = 0;
	char *base = NULL;
	Slapi_DN *sdn = NULL;
	char *fstr = NULL;
	char **pbattrs = NULL;
	int conn_acq_flag = 0;
    
    g_incr_active_threadcnt();

    /* need to acquire a reference to this connection so that it will not
       be released or cleaned up out from under us */
    PR_Lock( ps->ps_pblock->pb_conn->c_mutex );
    conn_acq_flag = connection_acquire_nolock(ps->ps_pblock->pb_conn);    
    PR_Unlock( ps->ps_pblock->pb_conn->c_mutex );

	if (conn_acq_flag) {
		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d Could not acquire the connection - psearch aborted\n",
						ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
	}

    PR_Lock( psearch_list->pl_cvarlock );

    while ( (conn_acq_flag == 0) && !ps->ps_complete ) {
	/* Check for an abandoned operation */
	if ( ps->ps_pblock->pb_op == NULL || slapi_op_abandoned( ps->ps_pblock ) ) {
		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d The operation has been abandoned\n",
						ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
	    break;
	}
	if ( NULL == ps->ps_eq_head ) {
	    /* Nothing to do */
	    PR_WaitCondVar( psearch_list->pl_cvar, PR_INTERVAL_NO_TIMEOUT );
	} else {
	    /* dequeue the item */
	    int		attrsonly;
	    char	**attrs;
	    LDAPControl	**ectrls;
	    Slapi_Entry	*ec;
		Slapi_Filter	*f = NULL;
		
	    PR_Lock( ps->ps_lock );

		peq = ps->ps_eq_head;
		ps->ps_eq_head = peq->pe_next;
	    if ( NULL == ps->ps_eq_head ) {
			ps->ps_eq_tail = NULL;
	    }

	    PR_Unlock( ps->ps_lock );

	    /* Get all the information we need to send the result */
	    ec = peq->pe_entry;
	    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRS, &attrs );
	    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
	    if ( !ps->ps_send_entchg_controls || peq->pe_ctrls[0] == NULL ) {
		ectrls = NULL;
	    } else {
		ectrls = peq->pe_ctrls;
	    }

	    /*
	     * Send the result.  Since send_ldap_search_entry can block for
	     * up to 30 minutes, we relinquish all locks before calling it.
	     */
	    PR_Unlock(psearch_list->pl_cvarlock);

		/*
		 * The entry is in the right scope and matches the filter
		 * but we need to redo the filter test here to check access
		 * controls. See the comments at the slapi_filter_test()
		 * call in ps_service_persistent_searches().		 
		*/
		slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_FILTER, &f );			

		/* See if the entry meets the filter and ACL criteria */
		if ( slapi_vattr_filter_test( ps->ps_pblock, ec, f,
			    1 /* verify_access */ ) == 0 ) {
			int rc = 0;
	    	slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_RESULT_ENTRY, ec );
	    	rc = send_ldap_search_entry( ps->ps_pblock, ec,
										 ectrls, attrs, attrsonly );
			if (rc) {
				slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
								"conn=%" NSPRIu64 " op=%d Error %d sending entry %s with op status %d\n",
								ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid,
								rc, slapi_entry_get_dn_const(ec), ps->ps_pblock->pb_op->o_status);
			}
		}
	    
		PR_Lock(psearch_list->pl_cvarlock);

		/* Deallocate our wrapper for this entry */
		pe_ch_free( &peq );
	}
    }
    PR_Unlock( psearch_list->pl_cvarlock );
    ps_remove( ps );

    /* indicate the end of search */
    plugin_call_plugins( ps->ps_pblock , SLAPI_PLUGIN_POST_SEARCH_FN );

	/* free things from the pblock that were not free'd in do_search() */
	/* we strdup'd this in search.c - need to free */
	slapi_pblock_get( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, &base );
	slapi_pblock_set( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, NULL );
	slapi_ch_free_string(&base);

	/* Free SLAPI_SEARCH_* before deleting op since those are held by op */
	slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, &sdn );
	slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, NULL );
	slapi_sdn_free(&sdn);

    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_STRFILTER, &fstr );
    slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_STRFILTER, NULL );
	slapi_ch_free_string(&fstr);

    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRS, &pbattrs );
    slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_ATTRS, NULL );
	if ( pbattrs != NULL )
	{
		charray_free( pbattrs );
	}
	
	slapi_pblock_get(ps->ps_pblock, SLAPI_SEARCH_FILTER, &filter );
	slapi_pblock_set(ps->ps_pblock, SLAPI_SEARCH_FILTER, NULL );
	slapi_filter_free(filter, 1);

    /* Clean up the connection structure */
    PR_Lock( ps->ps_pblock->pb_conn->c_mutex );

	slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
					"conn=%" NSPRIu64 " op=%d Releasing the connection and operation\n",
					ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
    /* Delete this op from the connection's list */
    connection_remove_operation( ps->ps_pblock->pb_conn, ps->ps_pblock->pb_op );
    operation_free(&(ps->ps_pblock->pb_op),ps->ps_pblock->pb_conn);
    ps->ps_pblock->pb_op=NULL;

    /* Decrement the connection refcnt */
    if (conn_acq_flag == 0) { /* we acquired it, so release it */
	connection_release_nolock (ps->ps_pblock->pb_conn);
    }
    PR_Unlock( ps->ps_pblock->pb_conn->c_mutex );

    PR_DestroyLock ( ps->ps_lock );
    ps->ps_lock = NULL;

    slapi_ch_free((void **) &ps->ps_pblock );
	for ( peq = ps->ps_eq_head; peq; peq = peqnext) {
		peqnext = peq->pe_next;
		pe_ch_free( &peq );
	}
    slapi_ch_free((void **) &ps );
    g_decr_active_threadcnt();
}
Exemplo n.º 17
0
Arquivo: uid.c Projeto: ohamada/389ds
static char *
create_filter(const char *attribute, const struct berval *value, const char *requiredObjectClass)
{
  char *filter;
  char *fp;
  char *max;
  int attrLen;
  int valueLen;
  int classLen = 0;
  int filterLen;

  PR_ASSERT(attribute);

  /* Compute the length of the required buffer */
  attrLen = strlen(attribute);

  if (ldap_quote_filter_value(value->bv_val, 
	value->bv_len, 0, 0, &valueLen))
    return 0;

  if (requiredObjectClass) {
    classLen = strlen(requiredObjectClass);
    /* "(&(objectClass=)())" == 19 */
    filterLen = attrLen + 1 + valueLen + classLen + 19 + 1;
  } else {
    filterLen = attrLen + 1 + valueLen + 1;
  }

  /* Allocate the buffer */
  filter = slapi_ch_malloc(filterLen);
  fp = filter;
  max = &filter[filterLen];

  /* Place AND expression and objectClass in filter */
  if (requiredObjectClass) {
    strcpy(fp, "(&(objectClass=");
    fp += 15;
    strcpy(fp, requiredObjectClass);
    fp += classLen;
    *fp++ = ')';
    *fp++ = '(';
  }

  /* Place attribute name in filter */
  strcpy(fp, attribute);
  fp += attrLen;

  /* Place comparison operator */
  *fp++ = '=';

  /* Place value in filter */
  if (ldap_quote_filter_value(value->bv_val, value->bv_len,
    fp, max-fp, &valueLen)) { slapi_ch_free((void**)&filter); return 0; }
  fp += valueLen;

  /* Close AND expression if a requiredObjectClass was set */
  if (requiredObjectClass) {
    *fp++ = ')';
    *fp++ = ')';
  }

  /* Terminate */
  *fp = 0;

  return filter;
}
Exemplo n.º 18
0
void
do_extended( Slapi_PBlock *pb )
{
    char        *extoid = NULL, *errmsg;
    struct berval   extval = {0};
    struct slapdplugin *p = NULL;
    int     lderr, rc;
    ber_len_t   len;
    ber_tag_t   tag;
    const char  *name;

    slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "->\n");

    /*
     * Parse the extended request. It looks like this:
     *
     *  ExtendedRequest := [APPLICATION 23] SEQUENCE {
     *      requestName [0] LDAPOID,
     *      requestValue    [1] OCTET STRING OPTIONAL
     *  }
     */

    if ( ber_scanf( pb->pb_op->o_ber, "{a", &extoid )
        == LBER_ERROR ) {
        slapi_log_err(SLAPI_LOG_ERR,
            "do_extended", "ber_scanf failed (op=extended; params=OID)\n");
        op_shared_log_error_access (pb, "EXT", "???", "decoding error: fail to get extension OID");
        send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0,
            NULL );
        goto free_and_return;
    }
    tag = ber_peek_tag(pb->pb_op->o_ber, &len);

    if (tag == LDAP_TAG_EXOP_REQ_VALUE) {
        if ( ber_scanf( pb->pb_op->o_ber, "o}", &extval ) == LBER_ERROR ) {
            op_shared_log_error_access (pb, "EXT", "???", "decoding error: fail to get extension value");
            send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0,
                              NULL );
            goto free_and_return;
        }
    } else {
        if ( ber_scanf( pb->pb_op->o_ber, "}") == LBER_ERROR ) {
            op_shared_log_error_access (pb, "EXT", "???", "decoding error"); 
            send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0,
                              NULL );
            goto free_and_return;
        }
    }
    if ( NULL == ( name = extended_op_oid2string( extoid ))) {
        slapi_log_err(SLAPI_LOG_ARGS, "do_extended", "oid (%s)\n", extoid);

        slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d EXT oid=\"%s\"\n",
                pb->pb_conn->c_connid, pb->pb_op->o_opid, extoid );
    } else {
        slapi_log_err(SLAPI_LOG_ARGS, "do_extended", "oid (%s-%s)\n",
                extoid, name);

        slapi_log_access( LDAP_DEBUG_STATS,
            "conn=%" NSPRIu64 " op=%d EXT oid=\"%s\" name=\"%s\"\n",
            pb->pb_conn->c_connid, pb->pb_op->o_opid, extoid, name );
    }

    /* during a bulk import, only BULK_IMPORT_DONE is allowed! 
     * (and this is the only time it's allowed)
     */
    if (pb->pb_conn->c_flags & CONN_FLAG_IMPORT) {
        if (strcmp(extoid, EXTOP_BULK_IMPORT_DONE_OID) != 0) {
            send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL);
            goto free_and_return;
        }
        extop_handle_import_done(pb, extoid, &extval);
        goto free_and_return;
    }
    
    if (strcmp(extoid, EXTOP_BULK_IMPORT_START_OID) == 0) {
        extop_handle_import_start(pb, extoid, &extval);
        goto free_and_return;
    }

    if (strcmp(extoid, START_TLS_OID) != 0) {
        int minssf = config_get_minssf();

        /* If anonymous access is disabled and we haven't
         * authenticated yet, only allow startTLS. */
        if ((config_get_anon_access_switch() != SLAPD_ANON_ACCESS_ON) && ((pb->pb_op->o_authtype == NULL) ||
                    (strcasecmp(pb->pb_op->o_authtype, SLAPD_AUTH_NONE) == 0))) {
            send_ldap_result( pb, LDAP_INAPPROPRIATE_AUTH, NULL,
                "Anonymous access is not allowed.", 0, NULL );
            goto free_and_return;
        }

        /* If the minssf is not met, only allow startTLS. */
        if ((pb->pb_conn->c_sasl_ssf < minssf) && (pb->pb_conn->c_ssl_ssf < minssf) &&
            (pb->pb_conn->c_local_ssf < minssf)) {
            send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
                "Minimum SSF not met.", 0, NULL );
            goto free_and_return;
        }
    }

    /* If a password change is required, only allow the password
     * modify extended operation */
    if (!pb->pb_conn->c_isreplication_session &&
                pb->pb_conn->c_needpw && (strcmp(extoid, EXTOP_PASSWD_OID) != 0))
    {
        char *dn = NULL;
        slapi_pblock_get(pb, SLAPI_CONN_DN, &dn);

        (void)slapi_add_pwd_control ( pb, LDAP_CONTROL_PWEXPIRED, 0);
        op_shared_log_error_access (pb, "EXT", dn ? dn : "", "need new password");
        send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, NULL, 0, NULL );

        slapi_ch_free_string(&dn);
        goto free_and_return;
    }

    /* decode the optional controls - put them in the pblock */
    if ( (lderr = get_ldapmessage_controls( pb, pb->pb_op->o_ber, NULL )) != 0 )
    {
        char *dn = NULL;
        slapi_pblock_get(pb, SLAPI_CONN_DN, &dn);

        op_shared_log_error_access (pb, "EXT", dn ? dn : "", "failed to decode LDAP controls");
        send_ldap_result( pb, lderr, NULL, NULL, 0, NULL );

        slapi_ch_free_string(&dn);
        goto free_and_return;
    }

    slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_OID, extoid );
    slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_VALUE, &extval );
    slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &pb->pb_op->o_isroot);

    rc = plugin_determine_exop_plugins( extoid, &p );
    slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "Plugin_determine_exop_plugins rc %d\n", rc);

    if (plugin_call_plugins(pb, SLAPI_PLUGIN_PRE_EXTOP_FN) != SLAPI_PLUGIN_SUCCESS) {
        goto free_and_return;
    }

    if (rc == SLAPI_PLUGIN_EXTENDEDOP && p != NULL) {
        slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "Calling plugin ... \n");
        /*
         * Return values:
         *  SLAPI_PLUGIN_EXTENDED_SENT_RESULT: The result is already sent to the client. 
         *                                     There is nothing to do further.
         *  SLAPI_PLUGIN_EXTENDED_NOT_HANDLED: Unsupported extended operation
         *  LDAP codes (e.g., LDAP_SUCCESS): The result is not sent yet. Call send_ldap_result.
         */
        rc = plugin_call_exop_plugins( pb, p);

        slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "Called exop, got %d \n", rc);

    } else if (rc == SLAPI_PLUGIN_BETXNEXTENDEDOP && p != NULL) {

        slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "Calling betxn plugin ... \n");
        /* Look up the correct backend to use. */
        Slapi_Backend *be = plugin_extended_op_getbackend( pb, p );

        if ( be == NULL ) {
            slapi_log_err(SLAPI_LOG_ERR, "do_extended", "Plugin_extended_op_getbackend was unable to retrieve a backend!\n");
            rc = LDAP_OPERATIONS_ERROR;
        } else {
            /* We need to make a new be pb here because when you set SLAPI_BACKEND
             * you overwrite the plg parts of the pb. So if we re-use pb
             * you actually nuke the request, and everything hangs. (╯°□°)╯︵ ┻━┻
             */
            Slapi_PBlock *be_pb = NULL;
            be_pb = slapi_pblock_new();
            slapi_pblock_set(be_pb, SLAPI_BACKEND, be);

            int txn_rc = slapi_back_transaction_begin(be_pb);
            if (txn_rc) {
                slapi_log_err(SLAPI_LOG_ERR, "do_extended", "Failed to start be_txn for plugin_call_exop_plugins %d\n", txn_rc);
            } else {
                /*
                 * Return values:
                 *  SLAPI_PLUGIN_EXTENDED_SENT_RESULT: The result is already sent to the client. 
                 *                                     There is nothing to do further.
                 *  SLAPI_PLUGIN_EXTENDED_NOT_HANDLED: Unsupported extended operation
                 *  LDAP codes (e.g., LDAP_SUCCESS): The result is not sent yet. Call send_ldap_result.
                 */
                rc = plugin_call_exop_plugins( pb, p );
                slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "Called betxn exop, got %d \n", rc);
                if (rc == LDAP_SUCCESS || rc == SLAPI_PLUGIN_EXTENDED_SENT_RESULT) {
                    /* commit */
                    txn_rc = slapi_back_transaction_commit(be_pb);
                    if (txn_rc == 0) {
                        slapi_log_err(SLAPI_LOG_TRACE, "do_extended", "Commit with result %d \n", txn_rc);
                    } else {
                        slapi_log_err(SLAPI_LOG_ERR, "do_extended", "Unable to commit commit with result %d \n", txn_rc);
                    }
                } else {
                    /* abort */
                    txn_rc = slapi_back_transaction_abort(be_pb);
                    slapi_log_err(SLAPI_LOG_ERR, "do_extended", "Abort with result %d \n", txn_rc);
                }
            } /* txn_rc */
            slapi_pblock_destroy(be_pb); /* Clean up after ourselves */
        } /* if be */
    }

    if (plugin_call_plugins(pb, SLAPI_PLUGIN_POST_EXTOP_FN) != SLAPI_PLUGIN_SUCCESS) {
        goto free_and_return;
    }

    if ( SLAPI_PLUGIN_EXTENDED_SENT_RESULT != rc ) {
        if ( SLAPI_PLUGIN_EXTENDED_NOT_HANDLED == rc ) {
            lderr = LDAP_PROTOCOL_ERROR;    /* no plugin handled the op */
            errmsg = "unsupported extended operation";
        } else {
            if (rc != LDAP_SUCCESS) {
                slapi_log_err(SLAPI_LOG_ERR, "do_extended", "Failed with result %d \n", rc);
            }
            errmsg = NULL;
            lderr = rc;
        }
        send_ldap_result( pb, lderr, NULL, errmsg, 0, NULL );
    }
free_and_return:
    if (extoid)
        slapi_ch_free((void **)&extoid);
    if (extval.bv_val)
        slapi_ch_free((void **)&extval.bv_val);
    return;
}
Exemplo n.º 19
0
Arquivo: uid.c Projeto: ohamada/389ds
/*
 * preop_modify - pre-operation plug-in for modify
 */
static int
preop_modify(Slapi_PBlock *pb)
{

  int result = LDAP_SUCCESS;
  Slapi_PBlock *spb = NULL;
  LDAPMod **checkmods = NULL;
  int checkmodsCapacity = 0;
  char *errtext = NULL;
  char *attrName = NULL;

#ifdef DEBUG
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
      "MODIFY begin\n");
#endif

  BEGIN
    int err;
    char *markerObjectClass=NULL;
    char *requiredObjectClass=NULL;
    LDAPMod **mods;
    int modcount = 0;
    int ii;
    LDAPMod *mod;
    Slapi_DN *sdn = NULL;
    int isupdatedn;
    int argc;
    char **argv = NULL;

    /*
     * If this is a replication update, just be a noop.
     */
    err = slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &isupdatedn);
    if (err) { result = uid_op_error(60); break; }
    if (isupdatedn)
    {
      break;
    }

    /*
     * Get the arguments
     */
        result = getArguments(pb, &attrName, &markerObjectClass,
                                                  &requiredObjectClass);
        if (UNTAGGED_PARAMETER == result)
        {
          result = LDAP_SUCCESS;
          /* Statically defined subtrees to monitor */
          err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGC, &argc);
          if (err) { result = uid_op_error(53); break; }

          err = slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
          if (err) { result = uid_op_error(54); break; }
          argc--; /* First argument was attribute name */
          argv++;
        } else if (0 != result)
        {
          break;
        }

    err = slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
    if (err) { result = uid_op_error(61); break; }

    /* There may be more than one mod that matches e.g.
       changetype: modify
       delete: uid
       uid: balster1950
       -
       add: uid
       uid: scottg
       
       So, we need to first find all mods that contain the attribute
       which are add or replace ops and are bvalue encoded
    */
    /* find out how many mods meet this criteria */
    for(;*mods;mods++)
    {
        mod = *mods;
        if ((slapi_attr_type_cmp(mod->mod_type, attrName, 1) == 0) && /* mod contains target attr */
            (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is bval encoded (not string val) */
            (mod->mod_bvalues && mod->mod_bvalues[0]) && /* mod actually contains some values */
            (SLAPI_IS_MOD_ADD(mod->mod_op) || /* mod is add */
             SLAPI_IS_MOD_REPLACE(mod->mod_op))) /* mod is replace */
        {
          addMod(&checkmods, &checkmodsCapacity, &modcount, mod);
        }
    }
    if (modcount == 0) {
        break; /* no mods to check, we are done */
    }

    /* Get the target DN */
    err = slapi_pblock_get(pb, SLAPI_MODIFY_TARGET_SDN, &sdn);
    if (err) { result = uid_op_error(11); break; }

    /*
     * Check if it has the required object class
     */
    if (requiredObjectClass &&
        !(spb = dnHasObjectClass(sdn, requiredObjectClass))) {
        break;
    }

    /*
     * Passed all the requirements - this is an operation we
     * need to enforce uniqueness on. Now find all parent entries
     * with the marker object class, and do a search for each one.
     */
    /*
     * stop checking at first mod that fails the check
     */
    for (ii = 0; (result == 0) && (ii < modcount); ++ii)
    {
        mod = checkmods[ii];
        if (NULL != markerObjectClass)
        {
            /* Subtree defined by location of marker object class */
            result = findSubtreeAndSearch(sdn, attrName, NULL, 
                                          mod->mod_bvalues, requiredObjectClass,
                                          sdn, markerObjectClass);
        } else
        {
            /* Subtrees listed on invocation line */
            result = searchAllSubtrees(argc, argv, attrName, NULL,
                                       mod->mod_bvalues, requiredObjectClass, sdn);
        }
    }
  END

  slapi_ch_free((void **)&checkmods);
  freePblock(spb);
 if (result)
  {
    slapi_log_error(SLAPI_LOG_PLUGIN, plugin_name,
      "MODIFY result %d\n", result);

    if (result == LDAP_CONSTRAINT_VIOLATION) {
      errtext = slapi_ch_smprintf(moreInfo, attrName);
    } else {
      errtext = slapi_ch_strdup("Error checking for attribute uniqueness.");
    }

    slapi_send_ldap_result(pb, result, 0, errtext, 0, 0);

    slapi_ch_free_string(&errtext);
  }

  return (result==LDAP_SUCCESS)?0:-1;

}
Exemplo n.º 20
0
int
acl_get_effective_rights (
	Slapi_PBlock    *pb,
	Slapi_Entry	    *e,			/* target entry */
	char			**attrs,	/* Attribute of	the entry */
	struct berval   *val,		/* value of attr. NOT USED */
	int		    	access,		/* requested access rights */
	char			**errbuf
	)
{
	Slapi_PBlock *gerpb = NULL;
	void *aclcb = NULL;
	char *subjectndn = NULL;
	char *gerstr = NULL;
	size_t gerstrsize = 0;
	size_t gerstrcap = 0;
	int iscritical = 1;
	int rc = LDAP_SUCCESS;

	*errbuf = '\0';

	if (NULL == e)	/* create a template entry from SLAPI_SEARCH_GERATTRS */
	{
		rc = _ger_generate_template_entry ( pb );
		slapi_pblock_get ( pb, SLAPI_SEARCH_RESULT_ENTRY, &e );
		if ( rc != LDAP_SUCCESS || NULL == e )
		{
			goto bailout;
		}
	}

	/*
	 * Get the subject
	 */
	rc = _ger_parse_control (pb, &subjectndn, &iscritical, errbuf );
	if ( rc != LDAP_SUCCESS )
	{
		goto bailout;
	}

	/*
	 * The requestor should have g permission on the entry
	 * to get the effective rights.
	 */
	rc = _ger_g_permission_granted (pb, e, subjectndn, errbuf);
	if ( rc != LDAP_SUCCESS )
	{
		goto bailout;
	}

	/*
	 * Construct a new pb
	 */
	rc = _ger_new_gerpb ( pb, e, subjectndn, &gerpb, &aclcb, errbuf );
	if ( rc != LDAP_SUCCESS )
	{
		goto bailout;
	}

	/* Get entry level effective rights */
	_ger_get_entry_rights ( gerpb, e, subjectndn, &gerstr, &gerstrsize, &gerstrcap, errbuf );

	/*
	 * Attribute level effective rights may not be NULL
	 * even if entry level's is.
	 */
	_ger_get_attrs_rights ( gerpb, e, subjectndn, attrs, &gerstr, &gerstrsize, &gerstrcap, errbuf );

bailout:
	/*
	 * Now construct the response control
	 */
	_ger_set_response_control ( pb, iscritical, rc );

	if ( rc != LDAP_SUCCESS )
	{
		gerstr = slapi_ch_smprintf("entryLevelRights: %d\nattributeLevelRights: *:%d", rc, rc );
	}

	slapi_log_error (SLAPI_LOG_ACLSUMMARY, plugin_name,
		"###### Effective Rights on Entry (%s) for Subject (%s) ######\n",
		e?slapi_entry_get_ndn(e):"null", subjectndn?subjectndn:"null");
	slapi_log_error (SLAPI_LOG_ACLSUMMARY, plugin_name, "%s\n", gerstr);

	/* Restore pb */
	_ger_release_gerpb ( &gerpb, &aclcb, pb );

	/*
	 * General plugin uses SLAPI_RESULT_TEXT for error text. Here
	 * SLAPI_PB_RESULT_TEXT is exclusively shared with add, dse and schema.
	 * slapi_pblock_set() will free any previous data, and
	 * pblock_done() will free SLAPI_PB_RESULT_TEXT.
	 */
	slapi_pblock_set (pb, SLAPI_PB_RESULT_TEXT, gerstr);

	if ( !iscritical )
	{
		/*
		 * If return code is not LDAP_SUCCESS, the server would
		 * abort sending the data of the entry to the client.
		 */
		rc = LDAP_SUCCESS;
	}

	slapi_ch_free ( (void **) &subjectndn );
	slapi_ch_free ( (void **) &gerstr );
	return rc;
}
Exemplo n.º 21
0
/* Creates and initializes a new ldbm_instance structure.
 * Also sets up some default indexes for the new instance.
 */
int ldbm_instance_create(backend *be, char *name)
{
    struct ldbminfo *li = (struct ldbminfo *) be->be_database->plg_private;
    ldbm_instance *inst = NULL;
    int rc = 0;

    /* Allocate storage for the ldbm_instance structure.  Information specific
     * to this instance of the ldbm backend will be held here. */
    inst = (ldbm_instance *) slapi_ch_calloc(1, sizeof(ldbm_instance));

    /* Record the name of this instance. */
    inst->inst_name = slapi_ch_strdup(name);

    /* initialize the entry cache */
    if (! cache_init(&(inst->inst_cache), DEFAULT_CACHE_SIZE,
                     DEFAULT_CACHE_ENTRIES, CACHE_TYPE_ENTRY)) {
        slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_create", "cache_init failed\n");
        rc = -1;
        goto error;
    }

    /*
     * initialize the dn cache 
     * We do so, regardless of the subtree-rename value.
     * It is needed when converting the db from DN to RDN format.
     */
    if (! cache_init(&(inst->inst_dncache), DEFAULT_DNCACHE_SIZE,
                     DEFAULT_DNCACHE_MAXCOUNT, CACHE_TYPE_DN)) {
        slapi_log_err(SLAPI_LOG_ERR,
                       "ldbm_instance_create", "dn cache_init failed\n");
        rc = -1;
        goto error;
    }

    /* Lock for the list of open db handles */
    inst->inst_handle_list_mutex = PR_NewLock();
    if (NULL == inst->inst_handle_list_mutex) {
        slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_create", "PR_NewLock failed\n");
        rc = -1;
        goto error;
    }

    /* Lock used to synchronize modify operations. */
    inst->inst_db_mutex = PR_NewMonitor();
    if (NULL == inst->inst_db_mutex) {
        slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_create", "PR_NewMonitor failed\n");
        rc = -1;
        goto error;
    }

    if ((inst->inst_config_mutex = PR_NewLock()) == NULL) {
        slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_create", "PR_NewLock failed\n");
        rc = -1;
        goto error;
    }

    if ((inst->inst_nextid_mutex = PR_NewLock()) == NULL) {
        slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_create", "PR_NewLock failed\n");
        rc = -1;
        goto error;
    }

    if ((inst->inst_indexer_cv = PR_NewCondVar(inst->inst_nextid_mutex)) == NULL) {
        slapi_log_err(SLAPI_LOG_ERR, "ldbm_instance_create", "PR_NewCondVar failed\n");
        rc = -1;
        goto error;
    }

    /* Keeps track of how many operations are currently using this instance */
    inst->inst_ref_count = slapi_counter_new();

    inst->inst_be = be;
    inst->inst_li = li;
    be->be_instance_info = inst;

    /* Initialize the fields with some default values. */
    ldbm_instance_config_setup_default(inst);

    /* Add this new instance to the the set of instances */
    {
        Object *instance_obj;

        instance_obj = object_new((void *) inst, &ldbm_instance_destructor);
        objset_add_obj(li->li_instance_set, instance_obj);
        object_release(instance_obj);
    }
    goto done;

error:
    slapi_ch_free_string(&inst->inst_name);
    slapi_ch_free((void**)&inst);

done:
    return rc;
}
Exemplo n.º 22
0
int
_ger_generate_template_entry (
	Slapi_PBlock    *pb
	)
{
	Slapi_Entry	*e = NULL;
	char **gerattrs = NULL;
	char **attrs = NULL;
	char **allowedattrs = NULL;
	char *templateentry = NULL;
	char *object = NULL;
	char *superior = NULL;
	char *p = NULL;
	const char *dn = NULL;
	Slapi_DN *sdn = NULL;
	char *dntype = NULL;
	int siz = 0;
	int len = 0;
	int i = 0;
	int notfirst = 0;
	int rc = LDAP_SUCCESS;

	slapi_pblock_get( pb, SLAPI_SEARCH_GERATTRS, &gerattrs );
	if (NULL == gerattrs)
	{
		slapi_log_error (SLAPI_LOG_FATAL, plugin_name,
						"Objectclass info is expected "
						"in the attr list, e.g., \"*@person\"\n");
		rc = LDAP_SUCCESS;
		goto bailout;
	}
	for (i = 0; gerattrs && gerattrs[i]; i++)
	{
		object = strchr(gerattrs[i], '@');
		if (NULL != object && '\0' != *(++object))
		{
			break;
		}
	}
	if (NULL == object)
	{
		rc = LDAP_SUCCESS;	/* no objectclass info; ok to return */
		goto bailout;
	}
	/* 
	 * Either @objectclass or @objectclass:dntype is accepted.
	 * If @objectclass, the first MUST attributetype (or the first MAY
	 * attributetype if MUST does not exist) is used for the attribute
	 * type in the leaf RDN.
	 * If @objectclass:dntype, dntype is used for the attribute type in the
	 * leaf RDN.
	 */
	dntype = strchr(object, ':');
	if (dntype) { /* @objectclasse:dntype */
		*dntype++ = '\0';
	}

	attrs = slapi_schema_list_objectclass_attributes(
						(const char *)object, SLAPI_OC_FLAG_REQUIRED);
	allowedattrs = slapi_schema_list_objectclass_attributes(
						(const char *)object, SLAPI_OC_FLAG_ALLOWED);
	charray_merge(&attrs, allowedattrs, 0 /* no copy */);
	slapi_ch_free((void **)&allowedattrs); /* free just allowedattrs */
	if (NULL == attrs) {
		rc = LDAP_SUCCESS;	/* bogus objectclass info; ok to return */
		goto bailout;
	}
	for (i = 0; attrs[i]; i++)
	{
		if (0 == strcasecmp(attrs[i], "objectclass"))
		{
			/* <*attrp>: <object>\n\0 */
			siz += strlen(attrs[i]) + 4 + strlen(object);
		}
		else
		{
			/* <*attrp>: (template_attribute)\n\0 */
			siz += strlen(attrs[i]) + 4 + 20;
		}
	}
	/* get the target dn where the template entry is located */
	slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
	dn = slapi_sdn_get_dn(sdn);
	if (dn)
	{
		/* dn: <attr>=<template_name>,<dn>\n\0 */
		if (dntype) {
			siz += strlen(dntype) + 30 + strlen(object) + strlen(dn);
		} else {
			siz += strlen(attrs[0]) + 30 + strlen(object) + strlen(dn);
		}
	}
	else
	{
		/* dn: <attr>=<template_name>\n\0 */
		if (dntype) {
			siz += strlen(dntype) + 30 + strlen(object);
		} else {
			siz += strlen(attrs[0]) + 30 + strlen(object);
		}
	}
	templateentry = (char *)slapi_ch_malloc(siz);
	if (NULL != dn && strlen(dn) > 0)
	{
		PR_snprintf(templateentry, siz,
		            "dn: %s=template_%s_objectclass,%s\n",
		            dntype?dntype:attrs[0], object, dn);
	}
	else
	{
		PR_snprintf(templateentry, siz,
		            "dn: %s=template_%s_objectclass\n",
		            dntype?dntype:attrs[0], object);
	}
	for (--i; i >= 0; i--)
	{
		len = strlen(templateentry);
		p = templateentry + len;
		if (0 == strcasecmp(attrs[i], "objectclass"))
		{
			PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
		}
		else
		{
			PR_snprintf(p, siz - len, "%s: (template_attribute)\n", attrs[i]);
		}
	}
	charray_free(attrs);

	while ((superior = slapi_schema_get_superior_name(object)) &&
			(0 != strcasecmp(superior, "top")))
	{
		if (notfirst)
		{
			slapi_ch_free_string(&object);
		}
		notfirst = 1;
		object = superior;
		attrs = slapi_schema_list_objectclass_attributes(
						(const char *)superior, SLAPI_OC_FLAG_REQUIRED);
		for (i = 0; attrs && attrs[i]; i++)
		{
			if (0 == strcasecmp(attrs[i], "objectclass"))
			{
				/* <*attrp>: <object>\n\0 */
				siz += strlen(attrs[i]) + 4 + strlen(object);
			}
		}
		templateentry = (char *)slapi_ch_realloc(templateentry, siz);
		for (--i; i >= 0; i--)
		{
			len = strlen(templateentry);
			p = templateentry + len;
			if (0 == strcasecmp(attrs[i], "objectclass"))
			{
				PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
			}
		}
		charray_free(attrs);
	}
	if (notfirst)
	{
		slapi_ch_free_string(&object);
	}
	slapi_ch_free_string(&superior);
	siz += 18; /* objectclass: top\n\0 */
	len = strlen(templateentry);
	templateentry = (char *)slapi_ch_realloc(templateentry, siz);
	p = templateentry + len;
	PR_snprintf(p, siz - len, "objectclass: top\n");

	e = slapi_str2entry(templateentry, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
	/* set the template entry to send the result to clients */
	slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, e);
bailout:
	slapi_ch_free_string(&templateentry);
	return rc;
}
Exemplo n.º 23
0
static int
passthru_bindpreop( Slapi_PBlock *pb )
{
    int			rc, method, freeresctrls=1;
    char		*matcheddn;
    const char	*normbinddn = NULL;
    Slapi_DN	*sdn = NULL;
    char		*libldap_errmsg, *pr_errmsg, *errmsg;
    PassThruConfig	*cfg;
    PassThruServer	*srvr;
    struct berval	*creds, **urls;
    LDAPControl		**reqctrls, **resctrls;

    PASSTHRU_ASSERT( pb != NULL );

    slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
	    "=> passthru_bindpreop\n" );

    /*
     * retrieve parameters for bind operation
     */
    if ( slapi_pblock_get( pb, SLAPI_BIND_METHOD, &method ) != 0 ||
        slapi_pblock_get( pb, SLAPI_BIND_TARGET_SDN, &sdn ) != 0 ||
        slapi_pblock_get( pb, SLAPI_BIND_CREDENTIALS, &creds ) != 0 ) {
        slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
                     "<= not handled (unable to retrieve bind parameters)\n" );
        return( PASSTHRU_OP_NOT_HANDLED );
    }
    normbinddn = slapi_sdn_get_dn(sdn);
    if ( normbinddn == NULL ) {
        normbinddn = "";
    }

    /*
     * We only handle simple bind requests that include non-NULL binddn and
     * credentials.  Let the Directory Server itself handle everything else.
     */
    if ( method != LDAP_AUTH_SIMPLE || *normbinddn == '\0'
	    || creds->bv_len == 0 ) {
	slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
		"<= not handled (not simple bind or NULL dn/credentials)\n" );
	return( PASSTHRU_OP_NOT_HANDLED );
    }

    /*
     * Get pass through authentication configuration.
     */
    cfg = passthru_get_config();

    /*
     * Check to see if the target DN is one we should "pass through" to
     * another server.
     */
    if ( passthru_dn2server( cfg, normbinddn, &srvr ) != LDAP_SUCCESS ) {
	slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
		"<= not handled (not one of our suffixes)\n" );
	return( PASSTHRU_OP_NOT_HANDLED );
    }

    /*
     * We are now committed to handling this bind request.
     * Chain it off to another server.
     */
    matcheddn = errmsg = libldap_errmsg = pr_errmsg = NULL;
    urls = NULL;
    resctrls = NULL;
    if ( slapi_pblock_get( pb, SLAPI_REQCONTROLS, &reqctrls ) != 0 ) {
	rc = LDAP_OPERATIONS_ERROR;
	errmsg = "unable to retrieve bind controls";
	slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM, "%s\n",
		errmsg );
    } else {
	int	lderrno;

	if (( rc = passthru_simple_bind_s( pb, srvr, PASSTHRU_CONN_TRIES,
		normbinddn, creds, reqctrls, &lderrno, &matcheddn,
		&libldap_errmsg, &urls, &resctrls )) == LDAP_SUCCESS ) {
	    rc = lderrno;
	    errmsg = libldap_errmsg;
	} else if ( rc != LDAP_USER_CANCELLED ) {	/* not abandoned */
	    PRErrorCode	prerr = PR_GetError();
	    pr_errmsg = PR_smprintf( "error %d - %s %s ("
		    SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
		    rc, ldap_err2string( rc ), srvr->ptsrvr_url,
		    prerr, slapd_pr_strerror(prerr));
	    if ( NULL != pr_errmsg ) {
		errmsg = pr_errmsg;
	    } else {
		errmsg = ldap_err2string( rc );
	    }
	    rc = LDAP_OPERATIONS_ERROR;
	}
    }

    /*
     * If bind succeeded, change authentication information associated
     * with this connection.
     */
    if ( rc == LDAP_SUCCESS ) {
        char *ndn = slapi_ch_strdup( normbinddn );
        if (slapi_pblock_set(pb, SLAPI_CONN_DN, ndn) != 0 ||
	    slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD,
                             SLAPD_AUTH_SIMPLE) != 0) {
            slapi_ch_free((void **)&ndn);
            rc = LDAP_OPERATIONS_ERROR;
            errmsg = "unable to set connection DN or AUTHTYPE";
            slapi_log_error( SLAPI_LOG_FATAL, PASSTHRU_PLUGIN_SUBSYSTEM,
                             "%s\n", errmsg );
        }
    }

    if ( rc != LDAP_USER_CANCELLED ) {	/* not abandoned */
	/*
	 * Send a result to our client.
	 */
	if ( resctrls != NULL ) {
	    (void)slapi_pblock_set( pb, SLAPI_RESCONTROLS, resctrls );
            freeresctrls=0;
	}
	slapi_send_ldap_result( pb, rc, matcheddn, errmsg, 0, urls );
    }

    /*
     * Clean up -- free allocated memory, etc.
     */
    if ( urls != NULL ) {
	passthru_free_bervals( urls );
    }
    if ( libldap_errmsg != NULL ) {
	ldap_memfree( errmsg );
    }
    if ( pr_errmsg != NULL ) {
	PR_smprintf_free( pr_errmsg );
    }
    if ( freeresctrls && (resctrls != NULL) ) {
	ldap_controls_free( resctrls );
    }
    if ( matcheddn != NULL ) {
	ldap_memfree( matcheddn );
    }
 
    slapi_log_error( SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
	    "<= handled (error %d - %s)\n", rc, ldap_err2string( rc ));

    return( PASSTHRU_OP_HANDLED );
}
Exemplo n.º 24
0
/*
 * Function: retrocl_create_config
 *
 * Returns: LDAP_
 * 
 * Arguments: none
 *
 * Description:
 * This function is called if there was no mapping tree node or backend for 
 * cn=changelog.
 */
int retrocl_create_config(void)
{
    Slapi_PBlock *pb = NULL;
    Slapi_Entry *e;
    struct berval *vals[2];
    struct berval val;
    int rc;
    char *mappingtree_dn = NULL;

    vals[0] = &val;
    vals[1] = NULL; 

    /* Assume the mapping tree node is missing.  It doesn't hurt to 
     * attempt to add it if it already exists.  You will see a warning
     * in the errors file when the referenced backend does not exist.
     */
    e = slapi_entry_alloc();
    /* This function converts the old DN style to the new one. */
    mappingtree_dn = slapi_create_dn_string("%s", RETROCL_MAPPINGTREE_DN);
    if (NULL == mappingtree_dn) {
        slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
                         "retrocl_create_config: failed to normalize "
                         "mappingtree dn %s\n", RETROCL_MAPPINGTREE_DN);
        return LDAP_PARAM_ERROR;
    }
    slapi_entry_set_dn(e, mappingtree_dn); /* mappingtree_dn is consumed */
    
    /* Set the objectclass attribute */
    val.bv_val = "top";
    val.bv_len = 3;
    slapi_entry_add_values( e, "objectclass", vals );

    
    /* Set the objectclass attribute */
    val.bv_val = "extensibleObject";
    val.bv_len = strlen(val.bv_val);
    slapi_entry_add_values( e, "objectclass", vals );

    /* Set the objectclass attribute */
    val.bv_val = "nsMappingTree";
    val.bv_len = strlen(val.bv_val);
    slapi_entry_add_values( e, "objectclass", vals );

    val.bv_val = "backend";
    val.bv_len = strlen(val.bv_val);
    slapi_entry_add_values( e, "nsslapd-state", vals );

    val.bv_val = RETROCL_CHANGELOG_DN;
    val.bv_len = strlen(val.bv_val);
    slapi_entry_add_values( e, "cn", vals );

    val.bv_val = "changelog";
    val.bv_len = strlen(val.bv_val);
    slapi_entry_add_values( e, "nsslapd-backend", vals );
    
    pb = slapi_pblock_new ();
    slapi_add_entry_internal_set_pb( pb, e, NULL /* controls */, 
				     g_plg_identity[PLUGIN_RETROCL], 
				     0 /* actions */ );
    slapi_add_internal_pb (pb);
    slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_RESULT, &rc );
    slapi_pblock_destroy(pb);
    
    if (rc == 0) {
        slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
			 "created changelog mapping tree node\n");
    } else if (rc == LDAP_ALREADY_EXISTS) {
        slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
			 "changelog mapping tree node already existed\n");
    } else {
        slapi_log_error( SLAPI_LOG_FATAL, RETROCL_PLUGIN_NAME, "cn=\"cn=changelog\",cn=mapping tree,cn=config could not be created (%d)\n", rc);
	return rc;
    }

    retrocl_be_changelog = slapi_be_select_by_instance_name("changelog");

    if (retrocl_be_changelog == NULL) {
        /* This is not the nsslapd-changelogdir from cn=changelog4,cn=config */
        char *bedir;

	bedir = retrocl_get_config_str(CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE);
	
	if (bedir == NULL) {
	    /* none specified */
	}

	rc = retrocl_create_be(bedir);
	slapi_ch_free ((void **)&bedir);
	if (rc != LDAP_SUCCESS && rc != LDAP_ALREADY_EXISTS) {
	    return rc;
	}

	retrocl_be_changelog = slapi_be_select_by_instance_name("changelog");
    }

    return LDAP_SUCCESS;
}
Exemplo n.º 25
0
int
aclinit_search_and_update_aci ( int thisbeonly, const Slapi_DN *base,
								char *be_name, int scope, int op,
								acl_lock_flag_t lock_flag )
{
	char				*attrs[2] = { "aci", NULL };
	 /* Tell __aclinit_handler whether it's an add or a delete */
	Slapi_PBlock 	*aPb;
	LDAPControl		**ctrls=NULL;
	struct berval	*bval;
	aclinit_handler_callback_data_t call_back_data;

	PR_ASSERT( lock_flag == DONT_TAKE_ACLCACHE_WRITELOCK ||
				lock_flag == DO_TAKE_ACLCACHE_WRITELOCK);

	if ( thisbeonly && be_name == NULL) {
		slapi_log_error ( SLAPI_LOG_FATAL, plugin_name, 
						"Error: This  be_name must be specified.\n");
		return -1;
	}


	/*
	 * We need to explicitly request (objectclass=ldapsubentry)
	 * in order to get all the subentry acis too.
	 * Note that subentries can be added under subentries (although its not
	 * recommended) so that
	 * there may be non-trivial acis under a subentry.
	*/ 

	/* Use new search internal API                 */
	/* and never retrieve aci from a remote server */
	aPb = slapi_pblock_new ();
		
	/*
	 * Set up the control to say "Only get acis from this Backend--
	 * there may be more backends under this one.
	*/

	if ( thisbeonly ) {		
		
		bval = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
		bval->bv_len = strlen(be_name) + 1;
		bval->bv_val = slapi_ch_strdup(be_name);

		ctrls = (LDAPControl **)slapi_ch_calloc( 2, sizeof(LDAPControl *));
		ctrls[0] = NULL;
		ctrls[1] = NULL;
	
		slapi_build_control_from_berval(
										MTN_CONTROL_USE_ONE_BACKEND_OID,
                						bval,
										1 /* is critical */, 
										ctrls);

	}	

	slapi_search_internal_set_pb (	aPb,
					slapi_sdn_get_dn(base),
					scope,
					"(|(aci=*)(objectclass=ldapsubentry))",
					attrs,
					0 /* attrsonly */,
					ctrls /* controls: SLAPI_ARGCONTROLS */,
					NULL /* uniqueid */,
					aclplugin_get_identity (ACL_PLUGIN_IDENTITY),
					SLAPI_OP_FLAG_NEVER_CHAIN /* actions : get local aci only */);
	
	if (thisbeonly) {
		slapi_pblock_set(aPb, SLAPI_REQCONTROLS, ctrls);
	}

	call_back_data.op = op;
	call_back_data.retCode = 0;
	call_back_data.lock_flag = lock_flag;

	slapi_search_internal_callback_pb(aPb,
					  &call_back_data /* callback_data */,
					  NULL/* result_callback */,
					  __aclinit_handler,
					  NULL /* referral_callback */);

	if (thisbeonly) {				
		slapi_ch_free((void **)&bval);				
	}	

	/*
	 * This frees the control oid, the bv_val and the control itself and the 
	 * ctrls array mem by caling ldap_controls_free()--so we
	 * don't need to do it ourselves.
	*/
	slapi_pblock_destroy (aPb);
	
	return call_back_data.retCode; 

}
Exemplo n.º 26
0
/*
 *
 * aclg_get_usersGroup
 *
 *	If we already have a the group info then we are done. If we
 *	don't, then allocate a new one and attach it.
 *
 *	Inputs:
 *		struct	acl_pblock		-- The acl private block.
 *		char *n_dn			- normalized client's DN
 *
 *	Returns:
 *		aclUserGroup			- The Group info block.
 *
 */
aclUserGroup *
aclg_get_usersGroup ( struct acl_pblock *aclpb , char *n_dn) 
{

	aclUserGroup		*u_group, *f_group;

	if ( !aclpb ) {
		slapi_log_error( SLAPI_LOG_ACL, plugin_name, "NULL acl pblock\n" );
		return NULL;
	}

	if ( aclpb->aclpb_groupinfo )
		return aclpb->aclpb_groupinfo;

	ACLG_LOCK_GROUPCACHE_WRITE();

	/* try it one more time. We might have one in the meantime */
	aclg_init_userGroup  (aclpb, n_dn , 1 /* got the lock */);
	if ( aclpb->aclpb_groupinfo ) {
		ACLG_ULOCK_GROUPCACHE_WRITE();
		return aclpb->aclpb_groupinfo;
	}

	/*
	 * It is possible at this point that we already have a group cache for the user
	 * but is is invalid. We can't use it anayway. So, we march along and allocate a new one.
	 * That's fine as the invalid one will be deallocated when done.
	 */

	slapi_log_error( SLAPI_LOG_ACL, plugin_name, "ALLOCATING GROUP FOR:%s\n", n_dn );
	u_group = ( aclUserGroup * ) slapi_ch_calloc ( 1, sizeof ( aclUserGroup ) );
	
	u_group->aclug_refcnt = 1;
	if ( (u_group->aclug_refcnt_mutex = PR_NewLock()) == NULL ) {
		slapi_ch_free((void **)&u_group);
		ACLG_ULOCK_GROUPCACHE_WRITE();
		return(NULL);
	}

	u_group->aclug_member_groups = (char **)
					slapi_ch_calloc ( 1, 
					    (ACLUG_INCR_GROUPS_LIST * sizeof (char *)));
	u_group->aclug_member_group_size = ACLUG_INCR_GROUPS_LIST;
	u_group->aclug_numof_member_group = 0;

	u_group->aclug_notmember_groups = (char **)
					slapi_ch_calloc ( 1,
					   (ACLUG_INCR_GROUPS_LIST * sizeof (char *)));
	u_group->aclug_notmember_group_size = ACLUG_INCR_GROUPS_LIST;
	u_group->aclug_numof_notmember_group = 0;

	u_group->aclug_ndn = slapi_ch_strdup ( n_dn ) ;	
	
	u_group->aclug_signature = aclUserGroups->aclg_signature;

	/* Do we have alreday the max number. If we have then delete the last one */
	if ( aclUserGroups->aclg_num_userGroups >= ACL_MAXCACHE_USERGROUPS - 5 ) {
		aclUserGroup		*d_group;
		
		/* We need to traverse thru  backwards and delete the one with a refcnt = 0 */
		d_group = aclUserGroups->aclg_last;
		while ( d_group ) {
			if ( !d_group->aclug_refcnt ) {
				__aclg__delete_userGroup ( d_group );
				break;
			} else {
				d_group = d_group->aclug_prev;
			}
		}

		/* If we didn't find any, which should be never, 
		** we have 5 more tries to do it.
		*/
	} 
	f_group = aclUserGroups->aclg_first;
	u_group->aclug_next = f_group;
	if ( f_group ) f_group->aclug_prev = u_group;
		
	aclUserGroups->aclg_first =  u_group;
	if ( aclUserGroups->aclg_last == NULL )
		aclUserGroups->aclg_last = u_group;

	aclUserGroups->aclg_num_userGroups++;

	/* Put it in the queue */
	ACLG_ULOCK_GROUPCACHE_WRITE();

	/* Now hang on to it */
	aclpb->aclpb_groupinfo = u_group;
	return u_group;
}
Exemplo n.º 27
0
void slapi_sdn_free( Slapi_DN **sdn )
{
	slapi_sdn_done( *sdn );
	slapi_ch_free( (void **)sdn );
}
Exemplo n.º 28
0
static int
agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *e,
	int *returncode, char *returntext, void *arg)
{
	int i;
	Slapi_DN *sdn = NULL;
	int start_initialize = 0, stop_initialize = 0, cancel_initialize = 0;
    int update_the_schedule = 0;	/* do we need to update the repl sched? */
	Repl_Agmt *agmt = NULL;
	LDAPMod **mods;
    char buff [SLAPI_DSE_RETURNTEXT_SIZE];
    char *errortext = returntext ? returntext : buff;
    int rc = SLAPI_DSE_CALLBACK_OK;
    Slapi_Operation *op;
    void *identity;

    *returncode = LDAP_SUCCESS;

     /* just let internal operations originated from replication plugin to go through */
    slapi_pblock_get (pb, SLAPI_OPERATION, &op);
    slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);                

    if (operation_is_flag_set(op, OP_FLAG_INTERNAL) &&
        (identity == repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION)))
    {
        goto done;
    }

    slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
    if (NULL == sdn) {
        slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, 
                        "agmtlist_modify_callback: NULL target dn\n");
        goto done;
    }
	agmt = agmtlist_get_by_agmt_name(sdn);
	if (NULL == agmt)
	{
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "agmtlist_modify_callback: received "
			"a modification for unknown replication agreement \"%s\"\n", 
			slapi_sdn_get_dn(sdn));
		goto done;
	}

	slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
	for (i = 0; NULL != mods && NULL != mods[i]; i++)
	{
		if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaInitialize))
		{
            /* we don't allow delete attribute operations unless it was issued by
               the replication plugin - handled above */
            if (mods[i]->mod_op & LDAP_MOD_DELETE)
            {
                if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0){
                    /* allow the deletion of cleanallruv agmt attr */
                    continue;
                }

                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "deletion of %s attribute is not allowed\n", type_nsds5ReplicaInitialize);	
                *returncode = LDAP_UNWILLING_TO_PERFORM;
                rc = SLAPI_DSE_CALLBACK_ERROR;
                break;
            }
            else
            {
                char *val;

                if (mods[i]->mod_bvalues && mods[i]->mod_bvalues[0])
                    val = slapi_berval_get_string_copy (mods[i]->mod_bvalues[0]);
                else
                {
                    slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "no value provided for %s attribute\n", type_nsds5ReplicaInitialize);
                    *returncode = LDAP_UNWILLING_TO_PERFORM;
                    rc = SLAPI_DSE_CALLBACK_ERROR;
                    break;   
                }

			    /* Start replica initialization */
                if (val == NULL)
                {
                    PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "No value supplied for attr (%s)", mods[i]->mod_type);
                    slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: %s\n",
                                    errortext);	  
                    *returncode = LDAP_UNWILLING_TO_PERFORM;
                    rc = SLAPI_DSE_CALLBACK_ERROR;
                    break;
                }
            
                if (strcasecmp (val, "start") == 0)
                {                        
                    start_initialize = 1;
                }
                else if (strcasecmp (val, "stop") == 0)
                {
                    stop_initialize = 1;
                }
                else if (strcasecmp (val, "cancel") == 0)
                {
                    cancel_initialize = 1;
                }
                else
                {
                    PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value (%s) value supplied for attr (%s)", 
                             val, mods[i]->mod_type);
                    slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: %s\n", errortext);
                }
                slapi_ch_free ((void**)&val);
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaUpdateSchedule))
		{
			/*
			 * Request to update the replication schedule.  Set a flag so
			 * we know to update the schedule later.
			 */
			update_the_schedule = 1;
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaCredentials))
		{
			/* New replica credentials */
			if (agmt_set_credentials_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update credentials for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaTimeout))
		{
			/* New replica timeout */
			if (agmt_set_timeout_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update timeout for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaBusyWaitTime))
		{
			/* New replica busywaittime */
			if (agmt_set_busywaittime_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update busy wait time for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaSessionPauseTime))
		{
			/* New replica pausetime */
			if (agmt_set_pausetime_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update session pause time for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaBindDN))
		{
			/* New replica Bind DN */
			if (agmt_set_binddn_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update bind DN for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
		                                     type_nsds5ReplicaPort))
		{
			/* New replica port */
			if (agmt_set_port_from_entry(agmt, e) != 0)
			{
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
				                "agmtlist_modify_callback: " 
				                "failed to update port for agreement %s\n",
				                agmt_get_long_name(agmt));	
				*returncode = LDAP_OPERATIONS_ERROR;
				rc = SLAPI_DSE_CALLBACK_ERROR;
			}
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5TransportInfo))
		{
			/* New Transport info */
			if (agmt_set_transportinfo_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update transport info for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaBindMethod))
		{
			if (agmt_set_bind_method_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update bind method for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicatedAttributeList))
		{
			char **denied_attrs = NULL;
			/* New set of excluded attributes */
			if (agmt_set_replicated_attributes_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update replicated attributes for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
			/* Check that there are no verboten attributes in the exclude list */
			denied_attrs = agmt_validate_replicated_attributes(agmt, 0 /* incremental */);
			if (denied_attrs)
			{
				/* Report the error to the client */
				PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "attempt to exclude an illegal attribute in a fractional agreement");
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                            "attempt to exclude an illegal attribute in a fractional agreement\n");

				*returncode = LDAP_UNWILLING_TO_PERFORM;
				rc = SLAPI_DSE_CALLBACK_ERROR;
				/* Free the deny list if we got one */
				slapi_ch_array_free(denied_attrs);
				break;
			}
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicatedAttributeListTotal))
		{
			char **denied_attrs = NULL;
			/* New set of excluded attributes */
			if (agmt_set_replicated_attributes_total_from_entry(agmt, e) != 0)
			{
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
								"failed to update total update replicated attributes for agreement %s\n",
								agmt_get_long_name(agmt));
				*returncode = LDAP_OPERATIONS_ERROR;
				rc = SLAPI_DSE_CALLBACK_ERROR;
			}
			/* Check that there are no verboten attributes in the exclude list */
			denied_attrs = agmt_validate_replicated_attributes(agmt, 1 /* total */);
			if (denied_attrs)
			{
				/* Report the error to the client */
				PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "attempt to exclude an illegal total update "
						"attribute in a fractional agreement");
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
						"attempt to exclude an illegal total update attribute in a fractional agreement\n");

				*returncode = LDAP_UNWILLING_TO_PERFORM;
				rc = SLAPI_DSE_CALLBACK_ERROR;
				/* Free the deny list if we got one */
				slapi_ch_array_free(denied_attrs);
				break;
			}
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
											 "nsds5debugreplicatimeout"))
		{
			char *val = slapi_entry_attr_get_charptr(e, "nsds5debugreplicatimeout");
			repl5_set_debug_timeout(val);
			slapi_ch_free_string(&val);
		}
        else if (strcasecmp (mods[i]->mod_type, "modifytimestamp") == 0 ||
                 strcasecmp (mods[i]->mod_type, "modifiersname") == 0 ||
                 strcasecmp (mods[i]->mod_type, "description") == 0)
        {
            /* ignore modifier's name and timestamp attributes and the description. */
            continue;
        }
        else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaEnabled))
        {
            if(agmt_set_enabled_from_entry(agmt, e, returntext) != 0){
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
                    "failed to set replica agmt state \"enabled/disabled\" for %s\n",agmt_get_long_name(agmt));
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
        }
        else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaStripAttrs))
        {
            if(agmt_set_attrs_to_strip(agmt, e) != 0){
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
                    "failed to set replica agmt attributes to strip for %s\n",agmt_get_long_name(agmt));
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
        }
        else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e))
        {
            slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                            "modification of %s attribute is not allowed\n", mods[i]->mod_type);
            *returncode = LDAP_UNWILLING_TO_PERFORM;
            rc = SLAPI_DSE_CALLBACK_ERROR;
            break;
        }
	}

	if (stop_initialize)
	{
        agmt_stop (agmt);
    }
    else if (start_initialize)
    {
        if (agmt_initialize_replica(agmt) != 0) {
            /* The suffix/repl agmt is disabled */
            agmt_set_last_init_status(agmt, 0, NSDS50_REPL_DISABLED, NULL);
            if(agmt_is_enabled(agmt)){
                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Suffix is disabled");
            } else {
                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Replication agreement is disabled");
            }
            *returncode = LDAP_UNWILLING_TO_PERFORM;
            rc = SLAPI_DSE_CALLBACK_ERROR;
        }
    }
    else if (cancel_initialize)
    {
        agmt_replica_init_done(agmt);
    }

	if (update_the_schedule) 
    {
		if (agmt_set_schedule_from_entry(agmt, e) != 0)
        {
            slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                            "failed to update replication schedule for agreement %s\n",
                            agmt_get_long_name(agmt));	
            *returncode = LDAP_OPERATIONS_ERROR;
            rc = SLAPI_DSE_CALLBACK_ERROR;
        }
	}

done:
	if (NULL != agmt)
	{
		agmtlist_release_agmt(agmt);
	}

	return rc;
}
Exemplo n.º 29
0
/*
 * Initialise the 4.0 Changelog
 */
int changelog4_init ()
{
    int rc= 0; /* OK */
    Slapi_Backend *rbe;
	changeNumber first_change = 0UL, last_change = 0UL;
	int lderr;
	
    if (changelog4_create_be() < 0 )
	{
		rc= -1;
	}
	else
	{
	rc = changelog4_start_be ();
	}

    if(rc == 0)
	{
        rbe = get_repl_backend();
    	if(rbe!=NULL)
    	{
    	    /* We have a Change Log. Check it's valid. */
			/* changelog has to be started before its 
			   data version can be read */ 
            const char *sdv= get_server_dataversion();
    	    const char *cdv= get_changelog_dataversion();
			char *suffix = changelog4_get_suffix ();
			if(!cdv || strcmp(sdv,cdv)!=0)
			{
				
			    /* The SDV and CDV are not the same.  The Change Log is invalid. 
			       It must be removed. */
				/* ONREPL - currently we go through this code when the changelog
				   is first created because we can't tell new backend from the
				   existing one.*/
				rc	= changelog4_close();
				rc	= changelog4_remove();

				/* now restart the changelog */
				changelog4_start_be ();

				create_entity( suffix, "extensibleobject");
                /* Write the Server Data Version onto the changelog suffix entry */
                /* JCMREPL - And the changelog database version number */
                set_changelog_dataversion(sdv);
				slapi_ch_free ((void **)&suffix);

			}
		}
	}
    
	if(rc != 0)
	{
		slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name, 
						"An error occurred configuring the changelog database\n" );
    }

	first_change = replog_get_firstchangenum( &lderr );
	last_change = replog_get_lastchangenum( &lderr );
	ldapi_initialize_changenumbers( first_change, last_change );

    return rc;
}
Exemplo n.º 30
0
static int
windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
{
	char *tmpstr = NULL;
	int retval = 0;
	
	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsReplicaArea))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsReplicaArea);
		if (NULL != tmpstr)
		{
			windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
		}
		retval = 1;
	}
	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7DirectoryReplicaArea))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7DirectoryReplicaArea); 
		if (NULL != tmpstr)
		{
			windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) );
		}
		retval = 1;
	}
	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewUsers))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewUsers); 
		if (NULL != tmpstr && true_value_from_string(tmpstr))
		{
			windows_private_set_create_users(ra, PR_TRUE);
		}
		else
		{
			windows_private_set_create_users(ra, PR_FALSE);
		}
		retval = 1;
		slapi_ch_free((void**)&tmpstr);
	}
	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewGroups))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewGroups); 
		if (NULL != tmpstr && true_value_from_string(tmpstr))
		{
			windows_private_set_create_groups(ra, PR_TRUE);
		}
		else
		{
			windows_private_set_create_groups(ra, PR_FALSE);
		}
		retval = 1;
		slapi_ch_free((void**)&tmpstr);
	}
	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsDomain))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsDomain); 
		if (NULL != tmpstr)
		{
			windows_private_set_windows_domain(ra,tmpstr);
		}
		/* No need to free tmpstr because it was aliased by the call above */
		tmpstr = NULL;
		retval = 1;
	}
	if (type == NULL || slapi_attr_types_equivalent(type,type_winSyncInterval))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_winSyncInterval); 
		if (NULL != tmpstr)
		{
			windows_private_set_sync_interval(ra,tmpstr);
		}
		slapi_ch_free_string(&tmpstr);
		retval = 1;
	}
	if (type == NULL || slapi_attr_types_equivalent(type,type_oneWaySync))
	{
		tmpstr = slapi_entry_attr_get_charptr(e, type_oneWaySync);
		if (NULL != tmpstr)
		{
			if (strcasecmp(tmpstr, "fromWindows") == 0) {
				windows_private_set_one_way(ra, ONE_WAY_SYNC_FROM_AD);
			} else if (strcasecmp(tmpstr, "toWindows") == 0) {
				windows_private_set_one_way(ra, ONE_WAY_SYNC_TO_AD);
			} else {
				slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
					"Ignoring illegal setting for %s attribute in replication "
					"agreement \"%s\".  Valid values are \"toWindows\" or "
					"\"fromWindows\".\n", type_oneWaySync, slapi_entry_get_dn(e));
				windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED);
			}
		}
		else
		{
			windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED);
		}
		slapi_ch_free((void**)&tmpstr);
		retval = 1;
	}
	return retval;
}