Ejemplo n.º 1
0
/* Attempt to require a symbol within the current scope.  If currently
 * within an optional (and not its else branch), add the symbol to the
 * required list.  Return 0 on success, 1 if caller needs to free()
 * datum.  If symbols may not be declared here return -1.  For duplicate
 * declarations return -2.  For all else, including out of memory,
 * return -3..  Note that dest_value and datum_value might not be
 * restricted pointers.
 */
int require_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value)
{
	avrule_decl_t *decl = stack_top->decl;
	int retval;

	/* first check that symbols may be required here */
	if (!is_require_allowed()) {
		return -1;
	}
	retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_REQ, decl->decl_id, dest_value);
	if (retval == 1) {
		symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table,
								      key);
		assert(s != NULL);

		if (symbol_type == SYM_LEVELS) {
			*dest_value = ((level_datum_t *) s)->level->sens;
		} else {
			*dest_value = s->value;
		}
	} else if (retval == -2) {
		/* ignore require statements if that symbol was
		 * previously declared and is in current scope */
		int prev_declaration_ok = 0;
		if (is_id_in_scope(symbol_type, key)) {
			if (symbol_type == SYM_TYPES) {
				/* check that previous symbol has same
				 * type/attribute-ness */
				unsigned char new_isattr = ((type_datum_t *) datum)->flavor;
				type_datum_t *old_datum = (type_datum_t *) hashtab_search(policydbp->symtab[SYM_TYPES].table, key);
				assert(old_datum != NULL);
				unsigned char old_isattr = old_datum->flavor;
				prev_declaration_ok = (old_isattr == new_isattr ? 1 : 0);
			} else {
				prev_declaration_ok = 1;
			}
		}
		if (prev_declaration_ok) {
			/* ignore this require statement because it
			 * was already declared within my scope */
			stack_top->require_given = 1;
			return 1;
		} else {
			/* previous declaration was not in scope or
			 * had a mismatched type/attribute, so
			 * generate an error */
			return -2;
		}
	} else if (retval < 0) {
		return -3;
	} else {		       /* fall through possible if retval is 0 or 1 */
	}
	if (datum_value != NULL) {
		if (ebitmap_set_bit(decl->required.scope + symbol_type, *datum_value - 1, 1)) {
			return -3;
		}
	}
	stack_top->require_given = 1;
	return retval;
}
Ejemplo n.º 2
0
/* Check if a particular permission is present within the given class,
 * and that the class is enabled.  Returns 1 if both conditions are
 * true, 0 if neither could be found or if the class id disabled. */
int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p)
{
	class_datum_t *cladatum;
	perm_datum_t *perm;
	if (!is_id_enabled(class_id, p, SYM_CLASSES)) {
		return 0;
	}
	cladatum =
	    (class_datum_t *) hashtab_search(p->p_classes.table, class_id);
	if (cladatum == NULL) {
		return 0;
	}
	perm = hashtab_search(cladatum->permissions.table, perm_id);
	if (perm == NULL && cladatum->comdatum != 0) {
		/* permission was not in this class.  before giving
		 * up, check the class's parent */
		perm =
		    hashtab_search(cladatum->comdatum->permissions.table,
				   perm_id);
	}
	if (perm == NULL) {
		return 0;
	}
	return 1;
}
int add_rule(char *s, char *t, char *c, char *p, policydb_t *policy) {
	type_datum_t *src, *tgt;
	class_datum_t *cls;
	perm_datum_t *perm;
	avtab_datum_t *av;
	avtab_key_t key;

	src = hashtab_search(policy->p_types.table, s);
	if (src == NULL) {
		fprintf(stderr, "source type %s does not exist\n", s);
		return 2;
	}
	tgt = hashtab_search(policy->p_types.table, t);
	if (tgt == NULL) {
		fprintf(stderr, "target type %s does not exist\n", t);
		return 2;
	}
	cls = hashtab_search(policy->p_classes.table, c);
	if (cls == NULL) {
		fprintf(stderr, "class %s does not exist\n", c);
		return 2;
	}
	perm = hashtab_search(cls->permissions.table, p);
	if (perm == NULL) {
		if (cls->comdatum == NULL) {
			fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
			return 2;
		}
		perm = hashtab_search(cls->comdatum->permissions.table, p);
		if (perm == NULL) {
			fprintf(stderr, "perm %s does not exist in class %s\n", p, c);
			return 2;
		}
	}

	// See if there is already a rule
	key.source_type = src->s.value;
	key.target_type = tgt->s.value;
	key.target_class = cls->s.value;
	key.specified = AVTAB_ALLOWED;
	av = avtab_search(&policy->te_avtab, &key);

	if (av == NULL) {
		int ret;

		av = cmalloc(sizeof av);
		av->data |= 1U << (perm->s.value - 1);
		ret = avtab_insert(&policy->te_avtab, &key, av);
		if (ret) {
			fprintf(stderr, "Error inserting into avtab\n");
			return 1;
		}	
	}

	av->data |= 1U << (perm->s.value - 1);

	return 0;
}
Ejemplo n.º 4
0
int qpol_policy_get_user_by_name(const qpol_policy_t * policy, const char *name, const qpol_user_t ** datum)
{
	hashtab_datum_t internal_datum;
	policydb_t *db;

	if (policy == NULL || name == NULL || datum == NULL) {
		if (datum != NULL)
			*datum = NULL;
		ERR(policy, "%s", strerror(EINVAL));
		errno = EINVAL;
		return STATUS_ERR;
	}

	db = &policy->p->p;
	internal_datum = hashtab_search(db->p_users.table, (hashtab_key_t)name);
	if (internal_datum == NULL) {
		*datum = NULL;
		ERR(policy, "could not find datum for user %s", name);
		errno = ENOENT;
		return STATUS_ERR;
	}
	*datum = (qpol_user_t *) internal_datum;

	return STATUS_SUCCESS;
}
Ejemplo n.º 5
0
/* Attempt to declare a symbol within the current declaration.  If
 * currently within a non-conditional and in a non-else branch then
 * insert the symbol, return 0 on success if symbol was undeclared.
 * For roles and users, it is legal to have multiple declarations; as
 * such return 1 to indicate that caller must free() the datum because
 * it was not added.  If symbols may not be declared here return -1.
 * For duplicate declarations return -2.  For all else, including out
 * of memory, return -3.  Note that dest_value and datum_value might
 * not be restricted pointers. */
int declare_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value)
{
	avrule_decl_t *decl = stack_top->decl;
	int retval;

	/* first check that symbols may be declared here */
	if (!is_declaration_allowed()) {
		return -1;
	}
	retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_DECL, decl->decl_id, dest_value);
	if (retval == 1 && dest_value) {
		symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table,
								      key);
		assert(s != NULL);

		if (symbol_type == SYM_LEVELS) {
			*dest_value = ((level_datum_t *) s)->level->sens;
		} else {
			*dest_value = s->value;
		}
	} else if (retval == -2) {
		return -2;
	} else if (retval < 0) {
		return -3;
	} else {		       /* fall through possible if retval is 0 */
	}
	if (datum_value != NULL) {
		if (ebitmap_set_bit(decl->declared.scope + symbol_type, *datum_value - 1, 1)) {
			return -3;
		}
	}
	return retval;
}
Ejemplo n.º 6
0
bool selinux_make_permissive(policydb_t *pdb, const std::string &type_str)
{
    type_datum_t *type;

    type = (type_datum_t *) hashtab_search(
            pdb->p_types.table, (hashtab_key_t) type_str.c_str());
    if (!type) {
        LOGV("Type %s not found in policy", type_str.c_str());
        return false;
    }

    if (ebitmap_get_bit(&pdb->permissive_map, type->s.value)) {
        LOGV("Type %s is already permissive", type_str.c_str());
        return true;
    }

    if (ebitmap_set_bit(&pdb->permissive_map, type->s.value, 1) < 0) {
        LOGE("Failed to set bit for type %s in the permissive map",
             type_str.c_str());
        return false;
    }

    LOGD("Type %s is now permissive", type_str.c_str());

    return true;
}
Ejemplo n.º 7
0
static oskit_error_t
recv(void *param, oskit_bufio_t *b, oskit_size_t pkt_size)
{
	oskit_pd_t *pd = (oskit_pd_t *)param;
	oskit_netio_t *netio;
	oskit_s32_t fid;
	oskit_s32_t err;
	char *pkt;

	osenv_assert(param);
	osenv_assert(b);

	err = oskit_bufio_map(b, (void **)&pkt, 0, pkt_size);
	if (err) {
		return OSKIT_E_UNEXPECTED;
	}

	switch (pd->ft) {
	case OSKIT_PD_FILTER_DPF_INTERP:
		fid = oskit_dpf_iptr(pkt, pkt_size);
		break;
	default:
		return OSKIT_E_NOTIMPL;
	}

	if (fid != 0) {
		netio = (oskit_netio_t *)hashtab_search(pd->ht, (hashtab_key_t)fid);
		osenv_assert(netio);
		oskit_netio_push(netio, b, pkt_size);
	} else {
		oskit_netio_push(pd->default_netio, b, pkt_size);
	}
	
	return 0;
}
Ejemplo n.º 8
0
/*
 * Return 1 if the MLS fields in the security context
 * structure `c' are valid.  Return 0 otherwise.
 */
int mls_context_isvalid(struct policydb *p, struct context *c)
{
	unsigned int relation;
	struct level_datum *levdatum;
	struct user_datum *usrdatum;
	struct mls_range_list *rnode;
	int i, l;

	/*
	 * MLS range validity checks: high must dominate low, low level must
	 * be valid (category set <-> sensitivity check), and high level must
	 * be valid (category set <-> sensitivity check)
	 */
	relation = mls_level_relation(c->range.level[1],
				      c->range.level[0]);
	if (!(relation & (MLS_RELATION_DOM | MLS_RELATION_EQ)))
		/* High does not dominate low. */
		return 0;

	for (l = 0; l < 2; l++) {
		if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim)
			return 0;
		levdatum = hashtab_search(p->p_levels.table,
			p->p_sens_val_to_name[c->range.level[l].sens - 1]);
		if (!levdatum)
			return 0;

		for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) {
			if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) {
				if (i > p->p_cats.nprim)
					return 0;
				if (!ebitmap_get_bit(&levdatum->level->cat, i - 1))
					/*
					 * Category may not be associated with
					 * sensitivity in low level.
					 */
					return 0;
			}
		}
	}

	if (c->role == OBJECT_R_VAL)
		return 1;

	/*
	 * User must be authorized for the MLS range.
	 */
	if (!c->user || c->user > p->p_users.nprim)
		return 0;
	usrdatum = p->user_val_to_struct[c->user - 1];
	for (rnode = usrdatum->ranges; rnode; rnode = rnode->next) {
		if (mls_range_contains(rnode->range, c->range))
			break;
	}
	if (!rnode)
		/* user may not be associated with range */
		return 0;

	return 1;
}
Ejemplo n.º 9
0
static bool is_type_of_attribute_set(policydb_t *policydb, const char *type_name,
        ebitmap_t *attr_set)
{
    struct type_datum *type = hashtab_search(policydb->p_types.table, (char *)type_name);
    if (!type) {
        fprintf(stderr, "Error: \"%s\" is not defined in this policy.\n", type_name);
        return false;
    }

    if (type->flavor != TYPE_TYPE) {
        fprintf(stderr, "Error: \"%s\" is not a type in this policy.\n", type_name);
        return false;
    }

    ebitmap_t dst;
    ebitmap_init(&dst);

    /* Take the intersection, if the set is empty, then its a failure */
    int rc = ebitmap_and(&dst, attr_set, &policydb->type_attr_map[type->s.value - 1]);
    if (rc) {
        fprintf(stderr, "Error: Could not perform ebitmap_and: %d\n", rc);
        exit(1);
    }

    bool res = (bool)ebitmap_length(&dst);

    ebitmap_destroy(&dst);
    return res;
}
Ejemplo n.º 10
0
static int user_implicit_bounds(hashtab_t users_tab, char *user_id, user_datum_t * user)
{
	user_datum_t *bounds;
	char *bounds_id, *delim;

	delim = strrchr(user_id, '.');
	if (!delim)
		return 0;	       /* no implicit boundary */

	bounds_id = strdup(user_id);
	if (!bounds_id) {
		yyerror("out of memory");
		return -1;
	}
	bounds_id[(size_t) (delim - user_id)] = '\0';

	bounds = hashtab_search(users_tab, bounds_id);
	if (!bounds) {
		yyerror2("user %s doesn't exist, is implicit bounds of %s", bounds_id, user_id);
		return -1;
	}

	if (!user->bounds)
		user->bounds = bounds->s.value;
	else if (user->bounds != bounds->s.value) {
		yyerror2("user %s has inconsistent bounds %s/%s",
			 user_id, bounds_id, policydbp->p_role_val_to_name[user->bounds - 1]);
		return -1;
	}
	free(bounds_id);

	return 0;
}
Ejemplo n.º 11
0
/*
 * Verify that each permission that is defined under the
 * existing policy is still defined with the same value
 * in the new policy.
 */
static int validate_perm(void *key, void *datum, void *p)
{
	struct hashtab *h;
	struct perm_datum *perdatum, *perdatum2;
	int rc = 0;


	h = p;
	perdatum = datum;

	perdatum2 = hashtab_search(h, key);
	if (!perdatum2) {
		printk(KERN_ERR "security:  permission %s disappeared",
		       (char *)key);
		rc = -ENOENT;
		goto out;
	}
	if (perdatum->value != perdatum2->value) {
		printk(KERN_ERR "security:  the value of permission %s changed",
		       (char *)key);
		rc = -EINVAL;
	}
out:
	return rc;
}
Ejemplo n.º 12
0
struct user *user_find(char *prefix)
{
	struct user *user;
	char nick[512];

	ircproto_parse_prefix(prefix, nick, sizeof(nick), NULL, 0, NULL, 0);
	user = hashtab_search(users, nick);
	return user;
}
Ejemplo n.º 13
0
static OSKIT_COMDECL filesystem_getroot(oskit_filesystem_t *f,
				       struct oskit_dir **out_dir)
{
    struct gfilesystem *fs = (struct gfilesystem *) f; 
    oskit_dir_t *d;
    struct proc *p;
    oskit_error_t ferror;
    struct vnode *vp;
    int error;

    if (!fs || !fs->count || !fs->mp)
	    return OSKIT_E_INVALIDARG;

    ferror = getproc(&p);
    if (ferror)
	    return ferror;
    
    error = VFS_ROOT(fs->mp, &vp);
    if (error)
    {
	prfree(p);
	return errno_to_oskit_error(error);
    }
    
    error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
    if (error)
    {
	vput(vp);
	prfree(p);
	return errno_to_oskit_error(error);
    }
    
    d = (oskit_dir_t *) hashtab_search(vptab, (hashtab_key_t) vp);
    if (d)
    {
	oskit_dir_addref(d);
    }
    else
    {
	d = (oskit_dir_t *) gfile_create(fs,vp);
	if (!d)
	{
	    vput(vp);
	    prfree(p);
	    return OSKIT_ENOMEM;
	}
    }

    vput(vp);
    prfree(p);
    *out_dir = d;
    return 0;    
}
Ejemplo n.º 14
0
/*
 * Convert the MLS fields in the security context
 * structure `c' from the values specified in the
 * policy `oldp' to the values specified in the policy `newp'.
 */
int mls_convert_context(struct policydb *oldp,
			struct policydb *newp,
			struct context *c)
{
	struct level_datum *levdatum;
	struct cat_datum *catdatum;
	struct ebitmap bitmap;
	int l, i;

	for (l = 0; l < 2; l++) {
		levdatum = hashtab_search(newp->p_levels.table,
			oldp->p_sens_val_to_name[c->range.level[l].sens - 1]);

		if (!levdatum)
			return -EINVAL;
		c->range.level[l].sens = levdatum->level->sens;

		ebitmap_init(&bitmap);
		for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) {
			if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) {
				int rc;

				catdatum = hashtab_search(newp->p_cats.table,
				         	oldp->p_cat_val_to_name[i - 1]);
				if (!catdatum)
					return -EINVAL;
				rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
				if (rc)
					return rc;
			}
		}
		ebitmap_destroy(&c->range.level[l].cat);
		c->range.level[l].cat = bitmap;
	}

	return 0;
}
Ejemplo n.º 15
0
static int get_attr_bit(policydb_t *policydb, const char *attr_name)
{
    struct type_datum *attr = hashtab_search(policydb->p_types.table, (char *)attr_name);
    if (!attr) {
        fprintf(stderr, "Error: \"%s\" is not defined in this policy.\n", attr_name);
        return -1;
    }

    if (attr->flavor != TYPE_ATTRIB) {
        fprintf(stderr, "Error: \"%s\" is not an attribute in this policy.\n", attr_name);
        return -1;
    }

    return attr->s.value - 1;
}
Ejemplo n.º 16
0
avrule_decl_t *test_find_decl_by_sym(policydb_t * p, int symtab, char *sym)
{
	scope_datum_t *scope = (scope_datum_t *) hashtab_search(p->scope[symtab].table, sym);

	if (scope == NULL) {
		return NULL;
	}
	if (scope->scope != SCOPE_DECL) {
		return NULL;
	}
	if (scope->decl_ids_len != 1) {
		return NULL;
	}

	return p->decl_val_to_struct[scope->decl_ids[0] - 1];
}
Ejemplo n.º 17
0
/*
 * Verify that each class that is defined under the
 * existing policy is still defined with the same
 * attributes in the new policy.
 */
static int validate_class(void *key, void *datum, void *p)
{
	struct policydb *newp;
	struct class_datum *cladatum, *cladatum2;
	int rc;

	newp = p;
	cladatum = datum;

	cladatum2 = hashtab_search(newp->p_classes.table, key);
	if (!cladatum2) {
		printk(KERN_ERR "security:  class %s disappeared\n",
		       (char *)key);
		rc = -ENOENT;
		goto out;
	}
	if (cladatum->value != cladatum2->value) {
		printk(KERN_ERR "security:  the value of class %s changed\n",
		       (char *)key);
		rc = -EINVAL;
		goto out;
	}
	if ((cladatum->comdatum && !cladatum2->comdatum) ||
	    (!cladatum->comdatum && cladatum2->comdatum)) {
		printk(KERN_ERR "security:  the inherits clause for the access "
		       "vector definition for class %s changed\n", (char *)key);
		rc = -EINVAL;
		goto out;
	}
	if (cladatum->comdatum) {
		rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm,
		                 cladatum2->comdatum->permissions.table);
		if (rc) {
			printk(" in the access vector definition for class "
			       "%s\n", (char *)key);
			goto out;
		}
	}
	rc = hashtab_map(cladatum->permissions.table, validate_perm,
	                 cladatum2->permissions.table);
	if (rc)
		printk(" in access vector definition for class %s\n",
		       (char *)key);
out:
	return rc;
}
Ejemplo n.º 18
0
/* Look up an identifier in a policy's scoping table.  If it is there,
 * marked as SCOPE_DECL, and any of its declaring block has been enabled,
 * then return 1.  Otherwise return 0. Can only be called after the 
 * decl_val_to_struct index has been created */
int is_id_enabled(char *id, policydb_t * p, int symbol_table)
{
	scope_datum_t *scope =
	    (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
	uint32_t i;
	if (scope == NULL) {
		return 0;
	}
	if (scope->scope != SCOPE_DECL) {
		return 0;
	}
	for (i = 0; i < scope->decl_ids_len; i++) {
		avrule_decl_t *decl =
		    p->decl_val_to_struct[scope->decl_ids[i] - 1];
		if (decl != NULL && decl->enabled) {
			return 1;
		}
	}
	return 0;
}
Ejemplo n.º 19
0
/* Return a role_datum_t for the local avrule_decl with the given ID.
 * If it does not exist, create one with the same value as 'value'.
 * This function assumes that the ID is within scope.  c.f.,
 * is_id_in_scope().
 *
 * NOTE: this function usurps ownership of id afterwards.  The caller
 * shall not reference it nor free() it afterwards.
 */
role_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr)
{
	role_datum_t *dest_roledatum;
	hashtab_t roles_tab;

	assert(stack_top->type == 1);

	if (stack_top->parent == NULL) {
		/* in global, so use global symbol table */
		roles_tab = policydbp->p_roles.table;
	} else {
		roles_tab = stack_top->decl->p_roles.table;
	}

	dest_roledatum = hashtab_search(roles_tab, id);
	if (!dest_roledatum) {
		dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t));
		if (dest_roledatum == NULL) {
			free(id);
			return NULL;
		}

		role_datum_init(dest_roledatum);
		dest_roledatum->s.value = value;
		dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE;

		if (hashtab_insert(roles_tab, id, dest_roledatum)) {
			free(id);
			role_datum_destroy(dest_roledatum);
			free(dest_roledatum);
			return NULL;
		}
	} else {
		free(id);
		if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE)
			return NULL;
	}
	
	return dest_roledatum;
}
Ejemplo n.º 20
0
static int bool_update(sepol_handle_t * handle,
		       policydb_t * policydb,
		       const sepol_bool_key_t * key, const sepol_bool_t * data)
{

	const char *cname;
	char *name;
	int value;

	sepol_bool_key_unpack(key, &cname);
	name = strdup(cname);
	value = sepol_bool_get_value(data);

	if (!name)
		goto omem;

	cond_bool_datum_t *datum =
	    hashtab_search(policydb->p_bools.table, name);
	if (!datum) {
		LOGD("boolean %s no longer in policy", name);
		goto err;
	}
	if (value != 0 && value != 1) {
		LOGD("illegal value %d for boolean %s", value, name);
		goto err;
	}

	free(name);
	datum->state = value;
	return STATUS_SUCCESS;

      omem:
	LOGD("out of memory");

      err:
	free(name);
	LOGD("could not update boolean %s", cname);
	return STATUS_ERR;
}
Ejemplo n.º 21
0
/* Return a type_datum_t for the local avrule_decl with the given ID.
 * If it does not exist, create one with the same value as 'value'.
 * This function assumes that the ID is within scope.  c.f.,
 * is_id_in_scope().
 *
 * NOTE: this function usurps ownership of id afterwards.  The caller
 * shall not reference it nor free() it afterwards.
 */
type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr)
{
	type_datum_t *dest_typdatum;
	hashtab_t types_tab;
	assert(stack_top->type == 1);
	if (stack_top->parent == NULL) {
		/* in global, so use global symbol table */
		types_tab = policydbp->p_types.table;
	} else {
		types_tab = stack_top->decl->p_types.table;
	}
	dest_typdatum = hashtab_search(types_tab, id);
	if (!dest_typdatum) {
		dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
		if (dest_typdatum == NULL) {
			free(id);
			return NULL;
		}
		type_datum_init(dest_typdatum);
		dest_typdatum->s.value = value;
		dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
		dest_typdatum->primary = 1;
		if (hashtab_insert(types_tab, id, dest_typdatum)) {
			free(id);
			type_datum_destroy(dest_typdatum);
			free(dest_typdatum);
			return NULL;
		}

	} else {
		free(id);
		if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) {
			return NULL;
		}
	}
	return dest_typdatum;
}
Ejemplo n.º 22
0
/* TODO: Looks fishy */
int bpool_delete(struct bpool *pool, char *id, int write_back) {
  if(pool && id) {
    struct bpool_node *node;

#ifdef BPOOL_ENABLE_LOCKS
    assert(0 == __bpool_lock(500, &pool->big_lock));
#endif

    node = hashtab_search(pool->table, id);
    if(node) {
#ifdef BPOOL_ENABLE_LOCKS
      assert(0 == __bpool_lock(501, &node->page_lock));
#endif

      assert(!node->dirty);
      hashtab_delete(pool->table, id);
      /* TODO: add facility to reset blocks */
      /*memset(node->id, 0, pool->PAGE_ID_SIZE);
	memset(node->buf, 0, pool->PAGE_SIZE);*/
      node->refbit = 0;
      node->valid  = 0;
      node->dirty  = 0;

#ifdef BPOOL_ENABLE_LOCKS
      assert(0 == __bpool_unlock(501, &node->page_lock));
#endif

    }

#ifdef BPOOL_ENABLE_LOCKS
    assert(0 == __bpool_unlock(500, &pool->big_lock));
#endif

  } // if pool && id
  return -2;
} 
Ejemplo n.º 23
0
int main ()
{
	
	int i = 0;
	int res = 0;
	char *pres = NULL;
	hashtab_node * node = NULL;
	struct test_node *p = NULL;
    hashtab *h = NULL;
    #ifdef MEMORY_TEST
	setenv("MALLOC_TRACE","1.txt",1);
    mtrace();
    #endif

	h = hashtab_create(5,hashtab_hvalue,hashtab_keycmp,hashtab_node_free);
    assert(h!= NULL);
	while(1)
	{
		p = (struct test_node*)malloc(sizeof(struct test_node));
		assert(p != NULL);
		printf("\r\n 请输入key 和value,当可以等于\"quit\"时退出");
        scanf("%s",p->key);
		scanf("%s",p->data);

		if(strcmp(p->key,"quit") == 0)
		{
			free(p);
			break;
		}

        res = hashtab_insert(h,p->key,p->data);
		if (res != 0)
		{
			free(p);
			printf("\r\n key[%s],data[%s] insert failed %d",p->key,p->data,res);
		}
		else
		{
			printf("\r\n key[%s],data[%s] insert success %d",p->key,p->data,res);
		}
	}

	hashtab_dump(h);

	while(1)
	{
		p = (struct test_node*)malloc(sizeof(struct test_node));
		assert(p != NULL);
		printf("\r\n 请输入key 查询value的数值,当可以等于\"quit\"时退出");
        scanf("%s",p->key);

		if(strcmp(p->key,"quit") == 0)
		{
			free(p);
			break;
		}
        pres = hashtab_search(h,p->key);
		if (pres == NULL)
		{
			printf("\r\n key[%s] search data failed",p->key);
		}
		else
		{
			printf("\r\n key[%s],search data[%s] success",p->key,pres);
		}
		free(p);
	}
	hashtab_dump(h);
	while(1)
	{
		p = (struct test_node*)malloc(sizeof(struct test_node));
		assert(p != NULL);
		printf("\r\n 请输入key 删除节点的数值,当可以等于\"quit\"时退出");
        scanf("%s",p->key);

		if(strcmp(p->key,"quit") == 0)
		{
			free(p);
			break;
		}
        node = hashtab_delete(h,p->key);
		if (node == NULL)
		{
			printf("\r\n key[%s] delete node failed ",p->key);
		}
		else
		{
			printf("\r\n key[%s],delete data[%s] success",node->key,node->data);
		    h->hash_node_free(node);
		}
		free(p);
	    hashtab_dump(h);
	}

	hashtab_destory(h);
    #ifdef MEMORY_TEST
    muntrace();
    #endif
	return 0;

}
Ejemplo n.º 24
0
/* Resume the deduping process that happens during the initial scanning.
 * We also use it as a building block in the run-time map creation
 * process as well, just by initializing the variables accordingly. 
 * P2D tuple consists of iodedupID to indicate which dedup block does
 * this pblk map into.
 *
 * @param[in] buf
 * @param[in] len
 * @param[in] ioblkID
 * @param[in] initflag
 * @param[in] lastblk_flag
 */
int resumeDeduping(unsigned char *buf, __u16 len,
		__u32 ioblkID, int initflag, int lastblk_flag, int rw_flag)
{
    //uint32_t ptime;  /* To be noted when event occurs, is this needed? TODO
	int ret;
	__u32 iodedupID;
	unsigned long long stime=0, etime=0;
    //savemem unsigned char dig[HASHLEN + MAGIC_SIZE];
	unsigned char *dig = malloc(HASHLEN + MAGIC_SIZE);
	unsigned char *key = NULL;
	d2pv_datum *dedupd2pv = NULL, *d2pv = NULL;
	D2P_tuple_t *d2p = NULL;
#ifdef STRICT_NO_HASH_COLLISION
	unsigned char *oldbuf = NULL;
    //savemem unsigned char debugkey[HASHLEN + MAGIC_SIZE];
	unsigned char* debugkey = malloc(HASHLEN + MAGIC_SIZE);
#endif
#if defined(DEDUPING_DEBUG_SSS)
	fprintf(stdout, "In %s\n", __FUNCTION__);
#endif

	 /* Buf will always have "len" == BLKSIZE. No leftovers.  */
#ifdef DEBUG_SS
		assert(len == BLKSIZE || lastblk_flag == ZEROBLK_FLAG);
		assert(initflag == INIT_STAGE || initflag == NOINIT_STAGE);
#endif

	if (len != 0)	/* Not a zero blk */
	{
		assert(buf != NULL);
		memset(dig, 0, HASHLEN);
		stime = gettime();	/* START IODEDUP map-update-get-hash time */
		if (getHashKey(buf, len, dig))
    	    RET_ERR("getHashKey() returned error\n");	
		etime = gettime();	/* END IODEDUP map-update-get-hash */
		ACCESSTIME_PRINT("iodedmap-map-update-component-get-hash time: %llu\n",
					 etime - stime);

		key = (unsigned char*)dig;
#if defined(SIMREPLAY_DEBUG_SS_DONE)
		printf("Content metadata update: buf=%s\n", (char*)buf);
		printf("Content metadata update: md5="); puts((char*)dig);
#endif

		if (cmaphit_flag && !disksimflag)
		{
			assert(REALDISK_SCANNING_NOCOLLECTFORMAT_VMBUNCHREPLAY);//assert(0);
			//no need to update metadata if this is read request with
			//metadata hit, and disk is real, not simulated!
			return 0;
		}
		else if (cmaphit_flag)	/* read with metadata hit but disk simulated */
		{
			//ideally, i.e. if traces are perfect, then
			//no need to update metadata here, just return, but.... 
			d2pv_datum *curr_d2pv = NULL;
			//but if the traces dont have consistent read/write requests,
			//in some cases of metadata-hit followed by cccahe-miss, the
			//following assert fails! work-around below...
			curr_d2pv = (d2pv_datum*) hashtab_search(deduptab.table, key);
#ifndef INCONSISTENT_TRACES
			assert(curr_d2pv != NULL);
#endif
			//work-around:
			//since we have already updated the content-cache with
			//the "offending content", we have to update the existing
			//metadata of this ioblk with new dhashkey, and also add
			//that new d2pv entry into deduptab (or update existing
			//dedupd2pv for the new dhashkey, if that is the case)

			d2pv_datum *cmaphit_d2pv = NULL; 	//found during metadata hit
			d2pv_datum *trace_d2pv = NULL;		//due to inconsistent trace,
												//if disk is being simulated
#ifdef INCONSISTENT_TRACES
			D2P_tuple_t *trace_d2p = NULL;
#endif
			cmaphit_d2pv = getDedupMap(cmaphit_iodedupID);
			assert(cmaphit_d2pv != NULL);
			trace_d2pv = (d2pv_datum*) hashtab_search(deduptab.table, key);
			if (cmaphit_d2pv == trace_d2pv)
				curr_d2pv = cmaphit_d2pv;	//true if trace is consistent
#ifndef INCONSISTENT_TRACES
			else
				RET_ERR("inconsistence why?\n");
#else
			else	//begin: fix for inconsistent trace
			{
				//trace is inconsistent, so we have to do some
				//impromptu metadata updates:-
				
				if (trace_d2pv == NULL)
				{
					__u32 iodedupID;
					trace_d2pv = (d2pv_datum*) calloc(1, sizeof(d2pv_datum));
		            INIT_LIST_HEAD(&trace_d2pv->d2pmaps);
		            iodedupID = getNextDedupNum(initflag);
					trace_d2p = calloc (1, sizeof(D2P_tuple_t));

/***************************************************************				
					if (ccache_already_had_flag)
					{
						note_dedup_attrs(trace_d2pv, key, iodedupID,
							ccache_already_had_obj_ioblkID);
						note_d2p_tuple(trace_d2p, 
							ccache_already_had_obj_ioblkID);
					}
					else
					{
						note_dedup_attrs(trace_d2pv, key, iodedupID, ioblkID);
			        	note_d2p_tuple(trace_d2p, ioblkID);
					}
***************************************************************/					
					/* We are here only upon a ccache miss after metadata hit,
					 * so ccache_already_had_flag == 0 mandatory!
					 */
					//assert(ccache_already_had_flag == 0);//not true for wif
					note_dedup_attrs(trace_d2pv, key, iodedupID, ioblkID);
					note_d2p_tuple(trace_d2p, ioblkID);
					add_d2p_tuple_to_map(trace_d2p, trace_d2pv);
					ret = hashtab_insert(deduptab.table, trace_d2pv->dhashkey, 
							trace_d2pv);
					setDedupMap(trace_d2pv->iodedupID, trace_d2pv);
					ret = updateBlockio(ioblkID, lastblk_flag, iodedupID);
					if (ret)
			            RET_ERR("updateBlockio() error'ed\n");
				}
				else
				{
					__u32 iodedupID;
					iodedupID = trace_d2pv->iodedupID;
					if (NULL == get_nondeduped_d2p(trace_d2pv, ioblkID))
					{
						trace_d2p = calloc (1, sizeof(D2P_tuple_t));
						//assert(ccache_already_had_flag == 0); //not true
						note_d2p_tuple(trace_d2p, ioblkID);
						add_d2p_tuple_to_map(trace_d2p, trace_d2pv);
					}
					ret = updateBlockio(ioblkID, lastblk_flag, iodedupID);
                    if (ret)
                        RET_ERR("updateBlockio() error'ed\n");
				}

				//if current ioblk is the only one in old sector-list,
				//then delete cmaphit_d2pv from hash-table, else let
				//it stay there.
				if (slist_len(&cmaphit_d2pv->d2pmaps) > 1)
				{
					del_d2p_from_d2pmaps(cmaphit_d2pv, ioblkID);
				}
				else
				{
					del_d2p_from_d2pmaps(cmaphit_d2pv, ioblkID);
					hashtab_remove(deduptab.table, cmaphit_d2pv->dhashkey); 
					setDedupMap(cmaphit_iodedupID, NULL);   //d2pv freed
				}

				//mark trace_d2pv as curr_d2pv for self-hits/misses below!
				curr_d2pv = trace_d2pv;

			}//end: fix for inconsistent trace
#endif

			//update the ioblkID for counts of self-hits/misses
			//copied from iodeduping.c, if change in 1 place, change both
            if (!ccache_already_had_flag)   //set in __arc_add 
                curr_d2pv->ioblkID = ioblkID;   //ensure counts line up -- self
            else
                curr_d2pv->ioblkID = ccache_already_had_obj_ioblkID;
			return 0;	
		}
Ejemplo n.º 25
0
			//update the ioblkID for counts of self-hits/misses
			//copied from iodeduping.c, if change in 1 place, change both
            if (!ccache_already_had_flag)   //set in __arc_add 
                curr_d2pv->ioblkID = ioblkID;   //ensure counts line up -- self
            else
                curr_d2pv->ioblkID = ccache_already_had_obj_ioblkID;
			return 0;	
		}

	    /* Note the D2P tuple for this dedup */
	    d2p = calloc (1, sizeof(D2P_tuple_t));
    	note_d2p_tuple(d2p, ioblkID);

		stime = gettime();	/* START IODEDUP map-update-hashtab-search time */
		dedupd2pv = (d2pv_datum*) hashtab_search(deduptab.table, key);
		if (dedupd2pv)
		{
			etime = gettime();	/* END IODEDUP map-update-hashtab-search time */
			ACCESSTIME_PRINT("iodedmap-map-update-component-hashtab-search-success time: %llu\n", etime - stime);
#ifdef STRICT_NO_HASH_COLLISION
			if (!disksimflag){
			if (!DISKSIM_RUNTIMEMAP_COLLECTFORMAT_VMBUNCHREPLAY &&
				!DISKSIM_RUNTIMEMAP_COLLECTFORMAT_PIOEVENTSREPLAY)
       		{
				assert(DISKSIM_SCANNINGTRACE_COLLECTFORMAT_PIOEVENTSREPLAY
					|| DISKSIM_RUNTIMEMAP_NOCOLLECTFORMAT_PIOEVENTSREPLAY);
				oldbuf = NULL;
				if (get_fulldedup(dedupd2pv, &oldbuf))
					RET_ERR("error in get_fulldedup\n");
				if (memcmp(buf, oldbuf, BLKSIZE))
Ejemplo n.º 26
0
user_datum_t *declare_user(void)
{
	char *id = queue_remove(id_queue), *dest_id = NULL;
	user_datum_t *user = NULL, *dest_user = NULL;
	int retval;
	uint32_t value = 0;

	if (id == NULL) {
		yyerror("no user name");
		return NULL;
	}
	if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) {
		yyerror("Out of memory!");
		free(id);
		return NULL;
	}
	user_datum_init(user);

	retval = declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, &value);

	if (retval == 0) {
		user->s.value = value;
		if ((dest_id = strdup(id)) == NULL) {
			yyerror("Out of memory!");
			return NULL;
		}
	} else {
		/* this user was already declared in this module, or error */
		dest_id = id;
		user_datum_destroy(user);
		free(user);
	}
	if (retval == 0 || retval == 1) {
		/* create a new user_datum_t for this decl, if necessary */
		hashtab_t users_tab;
		assert(stack_top->type == 1);
		if (stack_top->parent == NULL) {
			/* in parent, so use global symbol table */
			users_tab = policydbp->p_users.table;
		} else {
			users_tab = stack_top->decl->p_users.table;
		}
		dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id);
		if (dest_user == NULL) {
			if ((dest_user = (user_datum_t *) malloc(sizeof(*dest_user))) == NULL) {
				yyerror("Out of memory!");
				free(dest_id);
				return NULL;
			}
			user_datum_init(dest_user);
			dest_user->s.value = value;
			if (user_implicit_bounds(users_tab, dest_id, dest_user)) {
				free(dest_id);
				user_datum_destroy(dest_user);
				free(dest_user);
				return NULL;
			}
			if (hashtab_insert(users_tab, dest_id, dest_user)) {
				yyerror("Out of memory!");
				free(dest_id);
				user_datum_destroy(dest_user);
				free(dest_user);
				return NULL;
			}
		} else {
			free(dest_id);
		}
	} else {
		free(dest_id);
	}
	switch (retval) {
	case -3:{
		yyerror("Out of memory!");
		return NULL;
	}
	case -2:{
		yyerror("duplicate declaration of user");
		return NULL;
	}
	case -1:{
		yyerror("could not declare user here");
		return NULL;
	}
	case 0:{
		return dest_user;
	}
	case 1:{
		return dest_user;      /* user already declared for this block */
	}
	default:{
		assert(0);	       /* should never get here */
	}
	}
}
Ejemplo n.º 27
0
role_datum_t *declare_role(void)
{
	char *id = queue_remove(id_queue), *dest_id = NULL;
	role_datum_t *role = NULL, *dest_role = NULL;
	int retval;
	uint32_t value;

	if (id == NULL) {
		yyerror("no role name");
		return NULL;
	}
	if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) {
		yyerror("Out of memory!");
		free(id);
		return NULL;
	}
	role_datum_init(role);

	retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, &value);
	if (retval == 0) {
		role->s.value = value;
		if ((dest_id = strdup(id)) == NULL) {
			yyerror("Out of memory!");
			return NULL;
		}
	} else {
		/* this role was already declared in this module, or error */
		dest_id = id;
		role_datum_destroy(role);
		free(role);
	}
	if (retval == 0 || retval == 1) {
		/* create a new role_datum_t for this decl, if necessary */
		hashtab_t roles_tab;
		assert(stack_top->type == 1);
		if (stack_top->parent == NULL) {
			/* in parent, so use global symbol table */
			roles_tab = policydbp->p_roles.table;
		} else {
			roles_tab = stack_top->decl->p_roles.table;
		}
		dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id);
		if (dest_role == NULL) {
			if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) {
				yyerror("Out of memory!");
				free(dest_id);
				return NULL;
			}
			role_datum_init(dest_role);
			dest_role->s.value = value;
			if (role_implicit_bounds(roles_tab, dest_id, dest_role)) {
				free(dest_id);
				role_datum_destroy(dest_role);
				free(dest_role);
				return NULL;
			}
			if (hashtab_insert(roles_tab, dest_id, dest_role)) {
				yyerror("Out of memory!");
				free(dest_id);
				role_datum_destroy(dest_role);
				free(dest_role);
				return NULL;
			}
		} else {
			free(dest_id);
		}
	} else {
		free(dest_id);
	}
	switch (retval) {
	case -3:{
		yyerror("Out of memory!");
		return NULL;
	}
	case -2:{
		yyerror("duplicate declaration of role");
		return NULL;
	}
	case -1:{
		yyerror("could not declare role here");
		return NULL;
	}
	case 0:{
		if (ebitmap_set_bit(&dest_role->dominates, role->s.value - 1, 1)) {
			yyerror("out of memory");
			return NULL;
		}
		return dest_role;
	}
	case 1:{
		return dest_role;      /* role already declared for this block */
	}
	default:{
		assert(0);	       /* should never get here */
	}
	}
}
Ejemplo n.º 28
0
static void set_permissive(const hashtab_key_t domain, policydb_t *pdb)
{
    type_datum_t *type = hashtab_search(pdb->p_types.table, domain);
    ebitmap_set_bit(&pdb->permissive_map, type->s.value, 1);
}
int main_seinject(int argc, char **argv) {
	char *policy = NULL, *source = NULL, *target = NULL, *clazz = NULL, *perm = NULL, *perm_token = NULL, *perm_saveptr = NULL, *outfile = NULL, *permissive = NULL;
	policydb_t policydb;
	struct policy_file pf, outpf;
	sidtab_t sidtab;
	int ret_add_rule;
	int load = 0;
	int quiet = 0;
	FILE *fp;
	int i;

	for (i=1; i<argc; i++) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == 's') {
				i++;
				source = argv[i];
				continue;
			}
			if (argv[i][1] == 't') {
				i++;
				target = argv[i];
				continue;
			}
			if (argv[i][1] == 'c') {
				i++;
				clazz = argv[i];
				continue;
			}
			if (argv[i][1] == 'p') {
				i++;
				perm = argv[i];
				continue;
			}
			if (argv[i][1] == 'P') {
				i++;
				policy = argv[i];
				continue;
			}
			if (argv[i][1] == 'o') {
				i++;
				outfile = argv[i];
				continue;
			}
			if (argv[i][1] == 'Z') {
				i++;
				permissive = argv[i];
				continue;
			}
			if (argv[i][1] == 'l') {
				load = 1;
				continue;
			}
			if (argv[i][1] == 'q') {
				quiet = 1;
				continue;
			}
			break;
		}
	}

	if (i < argc || argc == 1 || ((!source || !target || !clazz || !perm) && !permissive)) {
		fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm>[,<perm2>,<perm3>,...] [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]);
		fprintf(stderr, "%s -Z permissive_type [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]);
		exit(1);
	}

	if (!policy)
		policy = "/sys/fs/selinux/policy";

	sepol_set_policydb(&policydb);
	sepol_set_sidtab(&sidtab);

	if (load_policy(policy, &policydb, &pf)) {
		fprintf(stderr, "Could not load policy\n");
		return 1;
	}

	if (policydb_load_isids(&policydb, &sidtab))
		return 1;

	if (permissive) {
		type_datum_t *type;
		type = hashtab_search(policydb.p_types.table, permissive);
		if (type == NULL) {
			fprintf(stderr, "type %s does not exist\n", permissive);
			return 2;
		}
		if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, 1)) {
			fprintf(stderr, "Could not set bit in permissive map\n");
			return 1;
		}
	} else {
		perm_token = strtok_r(perm, ",", &perm_saveptr);
		while (perm_token) {
			ret_add_rule = add_rule(source, target, clazz, perm_token, &policydb);
			if (ret_add_rule) {
				fprintf(stderr, "Could not add rule for perm: %s\n", perm_token);
				return ret_add_rule;
			}
			perm_token = strtok_r(NULL, ",", &perm_saveptr);
		}
	}

	if (outfile) {
		fp = fopen(outfile, "wb");
		if (!fp) {
			fprintf(stderr, "Could not open outfile\n");
			return 1;
		}

		policy_file_init(&outpf);
		outpf.type = PF_USE_STDIO;
		outpf.fp = fp;

		if (policydb_write(&policydb, &outpf)) {
			fprintf(stderr, "Could not write policy\n");
			return 1;
		}

		fclose(fp);
	}

	if (load) {
		if (load_policy_into_kernel(&policydb)) {
			fprintf(stderr, "Could not load new policy into kernel\n");
			return 1;
		}
	}

	policydb_destroy(&policydb);

	if (quiet == 0)
		fprintf(stdout, "Success\n");
	return 0;
}
Ejemplo n.º 30
0
static int load_booleans(struct policydb *policydb, const char *path,
			 int *changesp)
{
	FILE *boolf;
	char *buffer = NULL;
	size_t size = 0;
	char localbools[BUFSIZ];
	char name[BUFSIZ];
	int val;
	int errors = 0, changes = 0;
	struct cond_bool_datum *datum;

	boolf = fopen(path, "r");
	if (boolf == NULL)
		goto localbool;

#ifdef DARWIN
        if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) {
          ERR(NULL, "out of memory");
	  return -1;
	}

        while(fgets(buffer, 255, boolf) != NULL) {
#else
	while (getline(&buffer, &size, boolf) > 0) {
#endif
		int ret = process_boolean(buffer, name, sizeof(name), &val);
		if (ret == -1)
			errors++;
		if (ret == 1) {
			datum = hashtab_search(policydb->p_bools.table, name);
			if (!datum) {
				ERR(NULL, "unknown boolean %s", name);
				errors++;
				continue;
			}
			if (datum->state != val) {
				datum->state = val;
				changes++;
			}
		}
	}
	fclose(boolf);
      localbool:
	snprintf(localbools, sizeof(localbools), "%s.local", path);
	boolf = fopen(localbools, "r");
	if (boolf != NULL) {

#ifdef DARWIN

	  while(fgets(buffer, 255, boolf) != NULL) {
#else

	    while (getline(&buffer, &size, boolf) > 0) {
#endif
			int ret =
			    process_boolean(buffer, name, sizeof(name), &val);
			if (ret == -1)
				errors++;
			if (ret == 1) {
				datum =
				    hashtab_search(policydb->p_bools.table,
						   name);
				if (!datum) {
					ERR(NULL, "unknown boolean %s", name);
					errors++;
					continue;
				}
				if (datum->state != val) {
					datum->state = val;
					changes++;
				}
			}
		}
		fclose(boolf);
	}
	free(buffer);
	if (errors)
		errno = EINVAL;
	*changesp = changes;
	return errors ? -1 : 0;
}

int sepol_genbools(void *data, size_t len, char *booleans)
{
	struct policydb policydb;
	struct policy_file pf;
	int rc, changes = 0;

	if (policydb_init(&policydb))
		goto err;
	if (policydb_from_image(NULL, data, len, &policydb) < 0)
		goto err;

	if (load_booleans(&policydb, booleans, &changes) < 0) {
		WARN(NULL, "error while reading %s", booleans);
	}

	if (!changes)
		goto out;

	if (evaluate_conds(&policydb) < 0) {
		ERR(NULL, "error while re-evaluating conditionals");
		errno = EINVAL;
		goto err_destroy;
	}

	policy_file_init(&pf);
	pf.type = PF_USE_MEMORY;
	pf.data = data;
	pf.len = len;
	rc = policydb_write(&policydb, &pf);
	if (rc) {
		ERR(NULL, "unable to write new binary policy image");
		errno = EINVAL;
		goto err_destroy;
	}

      out:
	policydb_destroy(&policydb);
	return 0;

      err_destroy:
	policydb_destroy(&policydb);

      err:
	return -1;
}

int hidden sepol_genbools_policydb(policydb_t * policydb, const char *booleans)
{
	int rc, changes = 0;

	rc = load_booleans(policydb, booleans, &changes);
	if (!rc && changes)
		rc = evaluate_conds(policydb);
	if (rc)
		errno = EINVAL;
	return rc;
}

/* -- End Deprecated -- */

int sepol_genbools_array(void *data, size_t len, char **names, int *values,
			 int nel)
{
	struct policydb policydb;
	struct policy_file pf;
	int rc, i, errors = 0;
	struct cond_bool_datum *datum;

	/* Create policy database from image */
	if (policydb_init(&policydb))
		goto err;
	if (policydb_from_image(NULL, data, len, &policydb) < 0)
		goto err;

	for (i = 0; i < nel; i++) {
		datum = hashtab_search(policydb.p_bools.table, names[i]);
		if (!datum) {
			ERR(NULL, "boolean %s no longer in policy", names[i]);
			errors++;
			continue;
		}
		if (values[i] != 0 && values[i] != 1) {
			ERR(NULL, "illegal value %d for boolean %s",
			    values[i], names[i]);
			errors++;
			continue;
		}
		datum->state = values[i];
	}

	if (evaluate_conds(&policydb) < 0) {
		ERR(NULL, "error while re-evaluating conditionals");
		errno = EINVAL;
		goto err_destroy;
	}

	policy_file_init(&pf);
	pf.type = PF_USE_MEMORY;
	pf.data = data;
	pf.len = len;
	rc = policydb_write(&policydb, &pf);
	if (rc) {
		ERR(NULL, "unable to write binary policy");
		errno = EINVAL;
		goto err_destroy;
	}
	if (errors) {
		errno = EINVAL;
		goto err_destroy;
	}

	policydb_destroy(&policydb);
	return 0;

      err_destroy:
	policydb_destroy(&policydb);

      err:
	return -1;
}