Beispiel #1
0
/* Callback from hivex_node_delete_child which is called to delete a
 * node AFTER its subnodes have been visited.  The subnodes have been
 * deleted but we still have to delete any lf/lh/li/ri records and the
 * value list block and values, followed by deleting the node itself.
 */
static int
delete_node (hive_h *h, void *opaque, hive_node_h node, const char *name)
{
  /* Get the intermediate blocks.  The subkeys have already been
   * deleted by this point, so tell get_children() not to check for
   * validity of the nk-records.
   */
  hive_node_h *unused;
  size_t *blocks;
  if (_hivex_get_children (h, node,
                           &unused, &blocks, GET_CHILDREN_NO_CHECK_NK) == -1)
    return -1;
  free (unused);

  /* We don't care what's in these intermediate blocks, so we can just
   * delete them unconditionally.
   */
  size_t i;
  for (i = 0; blocks[i] != 0; ++i)
    mark_block_unused (h, blocks[i]);

  free (blocks);

  /* Delete the values in the node. */
  if (delete_values (h, node) == -1)
    return -1;

  struct ntreg_nk_record *nk =
    (struct ntreg_nk_record *) ((char *) h->addr + node);

  /* If the NK references an SK, delete it. */
  size_t sk_offs = le32toh (nk->sk);
  if (sk_offs != 0xffffffff) {
    sk_offs += 0x1000;
    if (delete_sk (h, sk_offs) == -1)
      return -1;
    nk->sk = htole32 (0xffffffff);
  }

  /* If the NK references a classname, delete it. */
  size_t cl_offs = le32toh (nk->classname);
  if (cl_offs != 0xffffffff) {
    cl_offs += 0x1000;
    mark_block_unused (h, cl_offs);
    nk->classname = htole32 (0xffffffff);
  }

  /* Delete the node itself. */
  mark_block_unused (h, node);

  return 0;
}
Beispiel #2
0
void delete_values(t_value *values)
{
	if (values == NULL)
	{
		return;
	}

	delete_values(values->next);
	free(values->name);
	free(values->value);
	free(values);

	return;
}
Beispiel #3
0
void delete_scopes(t_scope *scopes)
{
	if (scopes == NULL)
	{
		return;
	}

	delete_scopes(scopes->next);
	free(scopes->id);
	delete_values(scopes->variables);
	free(scopes);

	return;
}
Beispiel #4
0
void delete_state(t_state *state)
{
	delete_scopes(state->variables);
	delete_values(state->environ);
	free(state);
}
Beispiel #5
0
int
hivex_node_set_values (hive_h *h, hive_node_h node,
                       size_t nr_values, const hive_set_value *values,
                       int flags)
{
  CHECK_WRITABLE (-1);

  if (!IS_VALID_BLOCK (h, node) || !block_id_eq (h, node, "nk")) {
    SET_ERRNO (EINVAL, "invalid block or not an 'nk' block");
    return -1;
  }

  /* Delete all existing values. */
  if (delete_values (h, node) == -1)
    return -1;

  if (nr_values == 0)
    return 0;

  /* Allocate value list node.  Value lists have no id field. */
  static const char nul_id[2] = { 0, 0 };
  size_t seg_len =
    sizeof (struct ntreg_value_list) + (nr_values - 1) * sizeof (uint32_t);
  size_t vallist_offs = allocate_block (h, seg_len, nul_id);
  if (vallist_offs == 0)
    return -1;

  struct ntreg_nk_record *nk =
    (struct ntreg_nk_record *) ((char *) h->addr + node);
  nk->nr_values = htole32 (nr_values);
  nk->vallist = htole32 (vallist_offs - 0x1000);


  size_t i;
  for (i = 0; i < nr_values; ++i) {
    /* Allocate vk record to store this (key, value) pair. */
    static const char vk_id[2] = { 'v', 'k' };
    size_t recoded_name_len;
    int use_utf16;
    char* recoded_name = _hivex_encode_string (h, values[i].key, &recoded_name_len,
                                               &use_utf16);
    seg_len = sizeof (struct ntreg_vk_record) + recoded_name_len;
    size_t vk_offs = allocate_block (h, seg_len, vk_id);
    if (vk_offs == 0)
      return -1;

    /* Recalculate pointers that could have been invalidated by
     * previous call to allocate_block.
     */
    nk = (struct ntreg_nk_record *) ((char *) h->addr + node);
    struct ntreg_value_list *vallist =
      (struct ntreg_value_list *) ((char *) h->addr + vallist_offs);

    vallist->offset[i] = htole32 (vk_offs - 0x1000);

    struct ntreg_vk_record *vk =
      (struct ntreg_vk_record *) ((char *) h->addr + vk_offs);
    vk->name_len = htole16 (recoded_name_len);
    memcpy (vk->name, recoded_name, recoded_name_len);
    free (recoded_name);
    vk->data_type = htole32 (values[i].t);
    uint32_t len = values[i].len;
    if (len <= 4)               /* store it inline => set MSB flag */
      len |= 0x80000000;
    vk->data_len = htole32 (len);
    if (recoded_name_len == 0)
      vk->flags = 0;
    else
      vk->flags = htole16 (!use_utf16);

    if (values[i].len <= 4)     /* store it inline */
      memcpy (&vk->data_offset, values[i].value, values[i].len);
    else {
      size_t offs = allocate_block (h, values[i].len + 4, nul_id);
      if (offs == 0)
        return -1;

      /* Recalculate pointers that could have been invalidated by
       * previous call to allocate_block.
       */
      nk = (struct ntreg_nk_record *) ((char *) h->addr + node);
      /* vallist could be invalid here */
      vk = (struct ntreg_vk_record *) ((char *) h->addr + vk_offs);

      memcpy ((char *) h->addr + offs + 4, values[i].value, values[i].len);
      vk->data_offset = htole32 (offs - 0x1000);
    }

    size_t utf16_len = use_utf16 ? recoded_name_len : recoded_name_len * 2;
    if (utf16_len > le32toh (nk->max_vk_name_len))
      nk->max_vk_name_len = htole32 (utf16_len);
    if (values[i].len > le32toh (nk->max_vk_data_len))
      nk->max_vk_data_len = htole32 (values[i].len);
  }

  return 0;
}
Beispiel #6
0
static int 
monitor_subsys_log_modify( 
	Operation		*op,
	SlapReply		*rs,
	Entry 			*e )
{
	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
	int		rc = LDAP_OTHER;
	int		newlevel = ldap_syslog;
	Attribute	*save_attrs;
	Modifications	*modlist = op->orm_modlist;
	Modifications	*ml;

	ldap_pvt_thread_mutex_lock( &monitor_log_mutex );

	save_attrs = e->e_attrs;
	e->e_attrs = attrs_dup( e->e_attrs );

	for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
		Modification	*mod = &ml->sml_mod;

		/*
		 * accept all operational attributes;
		 * this includes modifersName and modifyTimestamp
		 * if lastmod is "on"
		 */
		if ( is_at_operational( mod->sm_desc->ad_type ) ) {
			( void ) attr_delete( &e->e_attrs, mod->sm_desc );
			rc = rs->sr_err = attr_merge( e, mod->sm_desc,
					mod->sm_values, mod->sm_nvalues );
			if ( rc != LDAP_SUCCESS ) {
				break;
			}
			continue;

		/*
		 * only the "managedInfo" attribute can be modified
		 */
		} else if ( mod->sm_desc != mi->mi_ad_managedInfo ) {
			rc = rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			break;
		}

		switch ( mod->sm_op ) {
		case LDAP_MOD_ADD:
			rc = add_values( op, e, mod, &newlevel );
			break;
			
		case LDAP_MOD_DELETE:
			rc = delete_values( op, e, mod, &newlevel );
			break;

		case LDAP_MOD_REPLACE:
			rc = replace_values( op, e, mod, &newlevel );
			break;

		default:
			rc = LDAP_OTHER;
			break;
		}

		if ( rc != LDAP_SUCCESS ) {
			rs->sr_err = rc;
			break;
		}
	}

	/* set the new debug level */
	if ( rc == LDAP_SUCCESS ) {
		const char	*text;
		static char	textbuf[ BACKMONITOR_BUFSIZE ];

		/* check for abandon */
		if ( op->o_abandon ) {
			rc = rs->sr_err = SLAPD_ABANDON;

			goto cleanup;
		}

		/* check that the entry still obeys the schema */
		rc = entry_schema_check( op, e, save_attrs, 0, 0, NULL,
			&text, textbuf, sizeof( textbuf ) );
		if ( rc != LDAP_SUCCESS ) {
			rs->sr_err = rc;
			goto cleanup;
		}

		/*
		 * Do we need to protect this with a mutex?
		 */
		ldap_syslog = newlevel;

#if 0	/* debug rather than log */
		slap_debug = newlevel;
		lutil_set_debug_level( "slapd", slap_debug );
		ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
		ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
		ldif_debug = slap_debug;
#endif
	}

cleanup:;
	if ( rc == LDAP_SUCCESS ) {
		attrs_free( save_attrs );

	} else {
		attrs_free( e->e_attrs );
		e->e_attrs = save_attrs;
	}
	
	ldap_pvt_thread_mutex_unlock( &monitor_log_mutex );

	if ( rc == LDAP_SUCCESS ) {
		rc = SLAP_CB_CONTINUE;
	}

	return rc;
}