1ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include <cil/android.h>
2ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include <sepol/policydb/hashtab.h>
3ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include <stdlib.h>
4ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include <string.h>
5ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
6ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include "cil_build_ast.h"
7ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include "cil_internal.h"
8ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include "cil_strpool.h"
9ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include "cil_symtab.h"
10ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#include "cil_tree.h"
11ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
12ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman#define VER_MAP_SZ (1 << 12)
13ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
14ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/* added to hashmap - currently unused as hashmap is used as a set */
15ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstruct version_datum {
16ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_db *db;
17ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_tree_node *ast_node;
18ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *orig_name;
19ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman};
20ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
21ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstruct version_args {
22ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_db *db;
23ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	hashtab_t vers_map;
24ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	const char *num;
25ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman};
26ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
272dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashmanenum plat_flavor {
282dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	PLAT_NONE = 0,
292dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	PLAT_TYPE,
302dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	PLAT_ATTRIB
312dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman};
322dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman
333b84f553e0e68d6ac5f9207449109b69d85a3621Nick Kralevichstatic unsigned int ver_map_hash_val(hashtab_t h, const_hashtab_key_t key)
34ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
35ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* from cil_stpool.c */
36ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *p, *keyp;
37ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	size_t size;
38ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	unsigned int val;
39ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
40ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	val = 0;
41ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	keyp = (char*)key;
42ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	size = strlen(keyp);
43ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	for (p = keyp; ((size_t) (p - keyp)) < size; p++)
44ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		val =
45ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			(val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
46ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return val & (h->size - 1);
47ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
48ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
49ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
50ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int ver_map_key_cmp(hashtab_t h __attribute__ ((unused)),
513b84f553e0e68d6ac5f9207449109b69d85a3621Nick Kralevich			   const_hashtab_key_t key1, const_hashtab_key_t key2)
52ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
533b84f553e0e68d6ac5f9207449109b69d85a3621Nick Kralevich	/* hashtab_key_t is just a const char* underneath */
543b84f553e0e68d6ac5f9207449109b69d85a3621Nick Kralevich	return strcmp(key1, key2);
55ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
56ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
57ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
58ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * version_datum  pointers all refer to memory owned elsewhere, so just free the
59ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * datum itself.
60ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
61ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int ver_map_entry_destroy(__attribute__ ((unused))hashtab_key_t k,
62ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman				 hashtab_datum_t d, __attribute__ ((unused))void *args)
63ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
64ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	free(d);
65ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return 0;
66ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
67ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
68ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic void ver_map_destroy(hashtab_t h)
69ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
70ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	hashtab_map(h, ver_map_entry_destroy, NULL);
71ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	hashtab_destroy(h);
72ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
73ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
74ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int __extract_attributees_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
75ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
76ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
77ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_args *args = (struct version_args *) extra_args;
78ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
79ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_datum *datum;
80ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
81ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (node == NULL || finished == NULL || extra_args == NULL) {
82ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
83ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
84ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
85ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	switch (node->flavor) {
86ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_ROLE:
87ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
88ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			CIL_KEY_ROLE, node->line);
89ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = SEPOL_ERR;
90ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
91ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPE:
92ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEATTRIBUTE:
93ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		datum = cil_malloc(sizeof(*datum));
94ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		datum->db = args->db;
95ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		datum->ast_node = node;
96ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		datum->orig_name = DATUM(node->data)->name;
97ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		key = datum->orig_name;
98ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (!strncmp(key, "base_typeattr_", 14)) {
99ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			/* checkpolicy creates base attributes which are just typeattributesets,
100ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			   of the existing types and attributes.  These may be differnt in
101ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			   every checkpolicy output, ignore them here, they'll be dealt with
1022dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman			   as a special case when attributizing. */
103d6ed837a4e4009e153382f1ff2495a13fc24856bAndreas Gampe			free(datum);
104ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		} else {
1052dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman			rc = hashtab_insert(args->vers_map, (hashtab_key_t) key, (hashtab_datum_t) datum);
106ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			if (rc != SEPOL_OK) {
107ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman				goto exit;
108ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			}
109ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
110ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
111ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEALIAS:
112ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
113ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			CIL_KEY_TYPEALIAS, node->line);
114ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
115ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
116ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEPERMISSIVE:
117ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
118ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			CIL_KEY_TYPEPERMISSIVE, node->line);
119ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
120ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
121ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_NAMETYPETRANSITION:
122ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPE_RULE:
123ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "%s unsupported statement in attributee policy (line %d)\n",
124ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			CIL_KEY_TYPETRANSITION, node->line);
125ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
126ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
127ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	default:
128ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
129ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
130ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
131ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
132ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
133ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
134ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
135ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
136ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * For the given db, with an already-built AST, fill the vers_map hash table
137ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * with every encountered type and attribute.  This could eventually be expanded
138ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * to include other language constructs, such as users and roles, in which case
139ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * multiple hash tables would be needed.  These tables can then be used by
140ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * attributize() to change all references to these types.
141ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
142ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanint cil_extract_attributees(struct cil_db *db, hashtab_t vers_map)
143ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
144ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* walk ast. */
145ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
146ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_args extra_args;
147ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.db = db;
148ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.vers_map = vers_map;
149ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.num = NULL;
150ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_tree_walk(db->ast->root, __extract_attributees_helper, NULL, NULL, &extra_args);
151ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
152ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
153ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
154ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
155ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
156ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
157ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
158ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
159ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
1602dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashmanstatic enum plat_flavor __cil_get_plat_flavor(hashtab_t vers_map, hashtab_key_t key)
1612dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman{
1622dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	enum plat_flavor rc;
1632dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	struct version_datum *vers_datum;
1642dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman
1652dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	vers_datum = (struct version_datum *)hashtab_search(vers_map, key);
1662dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (vers_datum == NULL) {
1672dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		return PLAT_NONE;
1682dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	}
1692dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	switch (vers_datum->ast_node->flavor) {
1702dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	case CIL_TYPE:
1712dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		rc = PLAT_TYPE;
1722dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		break;
1732dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	case CIL_TYPEATTRIBUTE:
1742dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		rc = PLAT_ATTRIB;
1752dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		break;
1762dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	default:
1772dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		rc = PLAT_NONE;
1782dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		break;
1792dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	}
1802dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	return rc;
1812dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman}
1822dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman
183ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
184ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * Takes the old name and version string and creates a new strpool entry by
185ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * combining them.
186ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
187ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic char *__cil_attrib_get_versname(char *old, const char *vers)
188ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
189ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	size_t len = 0;
190ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *tmp_new = NULL;
191ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *final;
192ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
193ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	len += strlen(old) + strlen(vers) + 2;
194ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	tmp_new = cil_malloc(len);
195ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	snprintf(tmp_new, len, "%s_%s", old, vers);
196ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	final = cil_strpool_add(tmp_new);
197ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	free(tmp_new);
198ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return final;
199ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
200ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
201ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
202ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * Change type to attribute - create new versioned name based on old, create
203ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * typeattribute node and replace existing type node.
204ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
205ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int __cil_attrib_convert_type(struct cil_tree_node *node, struct version_args *args)
206ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
207ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
208ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_type *type = (struct cil_type *)node->data;
209ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_typeattribute *typeattr = NULL;
210ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *new_key;
211ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
212ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_typeattribute_init(&typeattr);
213ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
214ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	new_key = __cil_attrib_get_versname(type->datum.name, args->num);
215ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
216ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_symtab_datum_remove_node(&type->datum, node);
217ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_destroy_type(type);
218ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
219ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_gen_node(args->db, node, (struct cil_symtab_datum *) typeattr,
220ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			  new_key, CIL_SYM_TYPES, CIL_TYPEATTRIBUTE);
221ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
222ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
223ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
224ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
225ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
226ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
227ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
228ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
229ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
230ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
231ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * Update datum - create new key, remove entry under old key,
232ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * update entry, and insert under new key
233ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
234ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int __cil_attrib_swap_symtab_key(struct cil_tree_node *node, char *old_key,
235ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman					const char *num)
236ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
237ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
238ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *new_key;
239ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	symtab_t *symtab;
240ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_symtab_datum *datum = (struct cil_symtab_datum *) node->data;
241ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
242ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	new_key = __cil_attrib_get_versname(old_key, num);
243ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
244ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	symtab = datum->symtab;
245ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
246ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* TODO: remove, but what happens to other nodes on this datum ?*/
247ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_list_remove(datum->nodes, CIL_NODE, node, 0);
248ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_symtab_remove_datum(datum);
249ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
250ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_symtab_insert(symtab, new_key, datum, node);
251ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
252ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
253ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
254ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
255ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
256ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
257ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
258ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
259ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
260ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
261ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
262ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * expressions may contains strings which are not in the type-attribute
263ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * namespace, so this is not a general cil_expr attributizer.
264ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * TODO: add support for other types of expressions which may contain types.
265ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
266ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_type_expr(struct cil_list *expr_str, struct version_args *args)
267ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
268ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
269ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_list_item *curr = NULL;
270ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *new;
2712dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	hashtab_key_t key;
272ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
273ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* iterate through cil_list, replacing types */
274ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_list_for_each(curr, expr_str) {
275ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		switch(curr->flavor) {
276ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		case CIL_LIST:
277ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			rc = cil_attrib_type_expr((struct cil_list *)curr->data, args);
278ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			if (rc != SEPOL_OK)
279ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman				goto exit;
280ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			break;
281ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		case CIL_STRING:
2822dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman			key = (hashtab_key_t) curr->data;
2832dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman			enum plat_flavor pf = __cil_get_plat_flavor(args->vers_map, key);
2842dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman			if (!strncmp(curr->data, "base_typeattr_", 14) || pf == PLAT_TYPE) {
285ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman				new = __cil_attrib_get_versname((char *) curr->data, args->num);
286ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman				curr->data = (void *) new;
287ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			}
288ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			break;
289ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		case CIL_DATUM:
290ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			cil_log(CIL_ERR, "AST already resolved. Not yet supported.\n");
291ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			rc = SEPOL_ERR;
292ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
293ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			break;
294ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		default:
295ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			break;
296ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
297ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
298ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
299ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
300ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
301ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
302ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
303ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
304ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_check_context(struct cil_context *ctxt, struct version_args *args)
305ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
306ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
3072dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	hashtab_key_t key;
308ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
309ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (ctxt->type != NULL) {
310ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved. Not yet supported.\n");
311ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
312ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
3132dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman
3142dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	key = (hashtab_key_t) ctxt->type_str;
3152dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, key) != PLAT_NONE) {
316ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman        /* TODO: reinstate check, but leave out for now
317ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST contains context with platform public type: %s\n",
318ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			ctxt->type_str);
319ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = SEPOL_ERR;
320ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit; */
321ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
322ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
323ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
324ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
325ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
326ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
327ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
328ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_sidcontext(struct cil_tree_node *node, struct version_args *args)
329ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
330ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
331ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_sidcontext *sidcon = (struct cil_sidcontext *)node->data;
332ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
333ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (sidcon->context_str == NULL) {
334ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* sidcon contains an anon context, which needs to have type checked */
335ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_check_context(sidcon->context, args);
336ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
337ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
338ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
339ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
340ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
341ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
342ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
343ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
344ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
345ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
346ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_context(struct cil_tree_node *node, struct version_args *args)
347ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
348ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_context *ctxt = (struct cil_context *)node->data;
349ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
350ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return cil_attrib_check_context(ctxt, args);
351ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
352ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
353ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_roletype(struct cil_tree_node *node,
354ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			       __attribute__((unused)) struct version_args *args)
355ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
356ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
357ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
358ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_roletype *roletype = (struct cil_roletype *)node->data;
359ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
360ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (roletype->role) {
361ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved.  !!! Not yet supported.\n");
362ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
363ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
364ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = roletype->type_str;
3652dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
366ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		roletype->type_str = __cil_attrib_get_versname(key, args->num);
367ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
368ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
369ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
370ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
371ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
372ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
373ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
374ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_type(struct cil_tree_node *node, struct version_args *args)
375ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
376ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
377ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_type *type = (struct cil_type *)node->data;
378ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key = type->datum.name;
379ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
380ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (type->value) {
381ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved.  !!! Not yet supported.\n");
382ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
383ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
3842dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
385ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = __cil_attrib_convert_type(node, args);
386ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
387ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
388ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
389ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
390ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
391ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
392ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
393ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
394ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
395ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
396a762060607d67cf9e9963bb3e856636dddadb1b1Jeff Vander Stoepstatic int cil_attrib_typepermissive(struct cil_tree_node *node,
397a762060607d67cf9e9963bb3e856636dddadb1b1Jeff Vander Stoep				     struct version_args *args __attribute__ ((unused)))
398ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
399ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_typepermissive *typeperm = (struct cil_typepermissive *)node->data;
400ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
401ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (typeperm->type != NULL) {
402ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved.  ### Not yet supported.\n");
403c4f2da434369e95184506ba4ef16da730f628f01William Roberts		return SEPOL_ERR;
404ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
405ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
406ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
407ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
408ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
409ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_typeattribute(struct cil_tree_node *node, struct version_args *args)
410ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
411ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
412ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_typeattribute *typeattr = (struct cil_typeattribute *)node->data;
413ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key = typeattr->datum.name;
414ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
415ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (typeattr->types) {
416ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
417ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			node->line);
418ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
419ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
4202dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (!strncmp(key, "base_typeattr_", 14)) {
421ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = __cil_attrib_swap_symtab_key(node, key, args->num);
422ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
423ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
424ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
4252dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	} else if (__cil_get_plat_flavor(args->vers_map, key) == PLAT_ATTRIB) {
4262dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		// platform attribute declaration to be provided by platform policy
4272dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		cil_symtab_datum_remove_node(&typeattr->datum, node);
4282dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		cil_destroy_typeattribute(typeattr);
4292dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		node->flavor = CIL_NONE; // traversal relies on this node sticking around, empty it.
430ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
431ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
432ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
433ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
434ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
435ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
436ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
437ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_typeattributeset(struct cil_tree_node *node, struct version_args *args)
438ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
439ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
440ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
441ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_typeattributeset *typeattrset = (struct cil_typeattributeset *) node->data;
442ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
443ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (typeattrset->datum_expr != NULL) {
444ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
445ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			node->line);
446ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
447ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
448ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
449ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = typeattrset->attr_str;
450ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* first check to see if the attribute to which this set belongs is versioned */
4512dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (!strncmp(key, "base_typeattr_", 14)) {
452ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		typeattrset->attr_str = __cil_attrib_get_versname(key, args->num);
453ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
454ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
455ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_attrib_type_expr(typeattrset->str_expr, args);
456ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
457ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
458ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
459ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
460ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
461ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
462ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
463ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
464ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
465ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_typealiasactual(struct cil_tree_node *node, struct version_args *args)
466ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
467ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
468ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
469ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_aliasactual *aliasact = (struct cil_aliasactual *)node->data;
470ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
471ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = aliasact->actual_str;
4722dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) != PLAT_NONE) {
473ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "%s with platform public type not allowed (line %d)\n",
474ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		    CIL_KEY_TYPEALIASACTUAL, node->line);
47550416106357a35a0200f32a4590a2f71d1d0c735dcashman		goto exit;
476ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
477ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
478ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
479ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
480ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
481ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
482ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
483ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_nametypetransition(struct cil_tree_node *node, struct version_args *args)
484ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
485ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
486ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
487ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_nametypetransition *namettrans = (struct cil_nametypetransition *)node->data;
488ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
489ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (namettrans->src != NULL) {
490ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
491ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			node->line);
492ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
493ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
494ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = namettrans->src_str;
4952dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
496ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		namettrans->src_str = __cil_attrib_get_versname(key, args->num);
497ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
498ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
499ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = namettrans->tgt_str;
5002dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
501ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		namettrans->tgt_str = __cil_attrib_get_versname(key, args->num);
502ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
503ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
504ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
505ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
506ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
507ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
508ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
509ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
510ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * This is exactly the same as cil_attrib_nametypetransition, but the struct
511ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * layouts differ, so we can't reuse it.
512ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
513ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_type_rule(struct cil_tree_node *node, struct version_args *args)
514ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
515ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
516ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
517ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_type_rule *type_rule = (struct cil_type_rule *)node->data;
518ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
519ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (type_rule->src != NULL) {
520ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
521ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			node->line);
522ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
523ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
524ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = type_rule->src_str;
5252dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
526ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		type_rule->src_str = __cil_attrib_get_versname(key, args->num);
527ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
528ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
529ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = type_rule->tgt_str;
5302dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (__cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
531ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		type_rule->tgt_str = __cil_attrib_get_versname(key, args->num);
532ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
533ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
534ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
535ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
536ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
537ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
538ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
539ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_avrule(struct cil_tree_node *node, struct version_args *args)
540ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
541ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
542ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *key;
543ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_avrule *avrule = (struct cil_avrule *)node->data;
544ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
545ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (avrule->src != NULL) {
546ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "AST already resolved. Not yet supported (line %d).\n",
547ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			node->line);
548ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
549ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
550ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
551ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = avrule->src_str;
552ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (!strncmp(key, "base_typeattr_", 14) ||
5532dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	    __cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
554ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		avrule->src_str = __cil_attrib_get_versname(key, args->num);
555ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
556ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
557ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	key = avrule->tgt_str;
558ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (!strncmp(key, "base_typeattr_", 14) ||
5592dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	    __cil_get_plat_flavor(args->vers_map, (hashtab_key_t) key) == PLAT_TYPE) {
560ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		avrule->tgt_str = __cil_attrib_get_versname(key, args->num);
561ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
562ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
563ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
564ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
565ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
566ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
567ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
568ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_genfscon(struct cil_tree_node *node, struct version_args *args)
569ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
570ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
571ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
572ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_genfscon *genfscon = (struct cil_genfscon *)node->data;
573ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
574ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (genfscon->context_str == NULL) {
575ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* genfscon contains an anon context, which needs to have type checked */
576ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_check_context(genfscon->context, args);
577ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
578ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
579ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
580ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
581ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
582ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
583ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
584ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
585ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
586ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
587ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_fsuse(struct cil_tree_node *node, struct version_args *args)
588ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
589ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
590ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_fsuse *fsuse = (struct cil_fsuse *)node->data;
591ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
592ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (fsuse->context_str == NULL) {
593ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* fsuse contains an anon context, which needs to have type checked */
594ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_check_context(fsuse->context, args);
595ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
596ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
597ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
598ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
599ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
600ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
601ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
602ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
603ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
604ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
605ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int __attributize_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
606ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
607ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
608ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_args *args = (struct version_args *) extra_args;
609ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
610ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (node == NULL || finished == NULL || extra_args == NULL) {
611ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
612ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
613ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
614ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	switch (node->flavor) {
615ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_SIDCONTEXT:
616ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* contains type, but shouldn't involve an attributized type, maybe add
617ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   a check on type and error if it conflicts */
618ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_sidcontext(node, args);
619ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
620ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
621ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
622ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
623ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_ROLE:
624ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "%s declaration illegal non-platform policy (line %d)\n",
625ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			CIL_KEY_ROLE, node->line);
626ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = SEPOL_ERR;
627ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
628ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_ROLETYPE:
629ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* Yes, this is needed if we support roletype in non-platform policy.
630ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   type_id can be type, typealias or typeattr */
631ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_roletype(node, args);
632ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
633ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
634ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
635ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
636ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_ROLEATTRIBUTE:
637ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* don't think this is needed, only used for cil_gen_req, and we aren't
638ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   yet supporting roles in non-platform policy. */
639ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
640ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPE:
641ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* conver to attribute if in policy */
642ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_type(node, args);
643ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
644ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
645ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
646ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
647ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEPERMISSIVE:
648ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_typepermissive(node, args);
649ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
650ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
651ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
652ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
653ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEATTRIBUTE:
654ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_typeattribute(node, args);
655ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
656ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
657ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
658ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
659ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEATTRIBUTESET:
660ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_typeattributeset(node, args);
661ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
662ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
663ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
664ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
665ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPEALIASACTUAL:
666ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* this will break on an attributized type - identify it and throw error */
667ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_typealiasactual(node, args);
668ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
669ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
670ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
671ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
672ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_NAMETYPETRANSITION:
673ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* not allowed in plat-policy. Types present, throw error if attributee */
674ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_nametypetransition(node, args);
675ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
676ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
677ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
678ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
679ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_TYPE_RULE:
680ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* not allowed in plat-policy. Types present, throw error if attributee */
681ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_type_rule(node, args);
682ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
683ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
684ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
685ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
686ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_AVRULE:
687ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_AVRULEX:
688ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_avrule(node, args);
689ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
690ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
691ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
692ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
693ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_CONTEXT:
694ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* not currently found in AOSP policy, but if found would need to be
695ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   checked to not be attributee */
696ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_context(node, args);
697ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
698ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
699ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
700ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
701ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_GENFSCON:
702ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* not allowed in plat-policy, but types present, throw error if attributee */
703ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = cil_attrib_genfscon(node, args);
704ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
705ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
706ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
707ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
708ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_FILECON:
709ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_NODECON:
710ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_PORTCON:
711ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_PIRQCON:
712ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_IOMEMCON:
713ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_IOPORTCON:
714ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_PCIDEVICECON:
715ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_DEVICETREECON:
716ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_VALIDATETRANS:
717ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_MLSVALIDATETRANS:
718ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_CALL:
719ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_MACRO:
720ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_OPTIONAL:
721ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* Not currently found in AOSP and not yet properly handled.  Return err until support added. */
722ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "unsupported policy statement (line %d)\n", node->line);
723ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = SEPOL_ERR;
724ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
725ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_FSUSE:
726ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* not allowed in plat-policy, but types present, throw error if attributee */
727ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_attrib_fsuse(node, args);
728ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		if (rc != SEPOL_OK) {
729ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman			goto exit;
730ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		}
731ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
732ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_CONSTRAIN:
733ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	case CIL_MLSCONSTRAIN:
734ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		/* there is type info here, but not sure if we'll allow non-platform code
735ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   to have this, or whether or not it's in platform policy.  Currently
736ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   assuming that mlsconstrain is private-platform only, and that normal
737ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		   constrain is verboten. */
738ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "unsupported policy statement (line %d)\n", node->line);
739ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		rc = SEPOL_ERR;
740ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
741ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	default:
742ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		break;
743ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
744ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
745ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
746ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
747ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
748ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
749ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
750ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
751ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * walk ast, replacing previously identified types and attributes with the
752ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * attributized version. Also replace previous references to the attributees
753ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * with the versioned type.
754ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
755ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attributize(struct cil_db *db, hashtab_t vers_map, const char *num)
756ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
757ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
758ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_args extra_args;
759ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.db = db;
760ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.vers_map = vers_map;
761ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.num = num;
762ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
763ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_tree_walk(db->ast->root, __attributize_helper, NULL, NULL, &extra_args);
764ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
765ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
766ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
767ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
768ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
769ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
770ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
771ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
772ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
773ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
774ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * Create typeattributeset mappings from the attributes generated from the
775ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * original types/attributes to the original values.  This mapping will provide
776ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * the basis for the platform policy's mapping to this public version.
777ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman *
778ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * Add these new typeattributeset nodes to the given cil_db.
779ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
7802dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashmanstatic int cil_build_mappings_tree(hashtab_key_t k, hashtab_datum_t d, void *args)
781ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
782ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_typeattributeset *attrset = NULL;
783574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	struct cil_expandtypeattribute *expandattr = NULL;
784ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_tree_node *ast_node = NULL;
785ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_args *verargs = (struct version_args *)args;
786ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct cil_tree_node *ast_parent = verargs->db->ast->root;
787ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	char *orig_type = (char *) k;
7882dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	struct version_datum *vers_datum = (struct version_datum *) d;
789ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
7902dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	if (vers_datum->ast_node->flavor == CIL_TYPEATTRIBUTE) {
7912dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		// platform attributes are not versioned
7922dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman		return SEPOL_OK;
7932dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	}
794ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* create typeattributeset datum */
795ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_typeattributeset_init(&attrset);
796ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_list_init(&attrset->str_expr, CIL_TYPE);
7972dec4336cbdd3dc766c6344bb5536b088b7d4e4ddcashman	attrset->attr_str = __cil_attrib_get_versname(orig_type, verargs->num);
798ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_list_append(attrset->str_expr, CIL_STRING, orig_type);
799ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
800ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* create containing tree node */
801ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_tree_node_init(&ast_node);
802ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ast_node->data = attrset;
803ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ast_node->flavor = CIL_TYPEATTRIBUTESET;
804ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
805ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* add to tree */
806ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ast_node->parent = ast_parent;
807ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (ast_parent->cl_head == NULL)
808ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		ast_parent->cl_head = ast_node;
809ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	else
810ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		ast_parent->cl_tail->next = ast_node;
811ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ast_parent->cl_tail = ast_node;
812574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep
813574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	/* create expandtypeattribute datum */
814574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	cil_expandtypeattribute_init(&expandattr);
815574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	cil_list_init(&expandattr->attr_strs, CIL_TYPE);
816574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	cil_list_append(expandattr->attr_strs, CIL_STRING, __cil_attrib_get_versname(orig_type, verargs->num));
817574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	expandattr->expand = CIL_TRUE;
818574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep
819574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	/* create containing tree node */
820574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	cil_tree_node_init(&ast_node);
821574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	ast_node->data = expandattr;
822574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	ast_node->flavor = CIL_EXPANDTYPEATTRIBUTE;
823574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	/* add to tree */
824574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	ast_node->parent = ast_parent;
825574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	ast_parent->cl_tail->next = ast_node;
826574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep	ast_parent->cl_tail = ast_node;
827574926fe6767a725e5fcc9576f3ba1e2c1dc3796Jeff Vander Stoep
828ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
829ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
830ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
831ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman/*
832ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * Initializes the given db and uses the version mapping generated by
833ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * cil_extract_attributees() to fill it with the glue policy required to
834ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * connect the attributized policy created by cil_attributize() to the policy
835ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman * declaring the concrete types.
836ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman */
837ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanstatic int cil_attrib_mapping(struct cil_db **db, hashtab_t vers_map, const char *num)
838ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
839ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
840ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	struct version_args extra_args;
841ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
842ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	cil_db_init(db);
843ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
844ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	/* foreach entry in vers_map, create typeattributeset node and attach to tree */
845ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.db = *db;
846ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.vers_map = NULL;
847ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	extra_args.num = num;
848ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = hashtab_map(vers_map, cil_build_mappings_tree, &extra_args);
849ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
850ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
851ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
852ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
853ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return SEPOL_OK;
854ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
855ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
856ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
857ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
858ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanint cil_android_attrib_mapping(struct cil_db **mdb, struct cil_db *srcdb, const char *num)
859ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
860ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
861ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	hashtab_t ver_map_tab = NULL;
862ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
863ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ver_map_tab = hashtab_create(ver_map_hash_val, ver_map_key_cmp, VER_MAP_SZ);
864ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (!ver_map_tab) {
865ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to create version mapping table.\n");
866ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
867ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
868ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_build_ast(srcdb, srcdb->parse->root, srcdb->ast->root);
869ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
870ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to build source db AST.\n");
871ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
872ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
873ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_extract_attributees(srcdb, ver_map_tab);
874ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
875ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to extract attributizable elements from source db.\n");
876ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
877ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
878ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_attrib_mapping(mdb, ver_map_tab, num);
879ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
880ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to create mapping db from source db.\n");
881ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
882ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
883ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
884ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ver_map_destroy(ver_map_tab);
885ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
886ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
887ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
888ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanint cil_android_attributize(struct cil_db *tgtdb, struct cil_db *srcdb, const char *num)
889ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman{
890ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	int rc = SEPOL_ERR;
891ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	hashtab_t ver_map_tab = NULL;
892ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman
893ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ver_map_tab = hashtab_create(ver_map_hash_val, ver_map_key_cmp, VER_MAP_SZ);
894ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (!ver_map_tab) {
895ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to create version mapping table.\n");
896ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
897ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
898ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_build_ast(srcdb, srcdb->parse->root, srcdb->ast->root);
899ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
900ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to build source db AST.\n");
901ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
902ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
903ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_extract_attributees(srcdb, ver_map_tab);
904ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
905ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to extract attributizable elements from source db.\n");
906ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
907ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
908ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_build_ast(tgtdb, tgtdb->parse->root, tgtdb->ast->root);
909ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
910ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to build target db AST.\n");
911ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
912ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
913ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	rc = cil_attributize(tgtdb, ver_map_tab, num);
914ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	if (rc != SEPOL_OK) {
915ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		cil_log(CIL_ERR, "Unable to attributize target db.\n");
916ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman		goto exit;
917ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	}
918ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashmanexit:
919ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	ver_map_destroy(ver_map_tab);
920ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman	return rc;
921ee5a1aef6bcf7cdd186bfa53eb4e6b5d98c5db9cdcashman}
922