libsepol:cil: Fix bugs in cil_reset_ast

- There was an issue in cil_reset where elements were reset
  regardless if they were anonymous or named.
- Add reset functions for userlevel and userrange

Signed-off-by: Yuli Khodorkovskiy <ykhodorkovskiy@tresys.com>
fix gcc -Wwrite-strings warnings

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
Disable declarations inside an optional even if in the first call pass

The first call pass might fail to resolve the name of a macro, e.g.

    (call does_not_exist (...))

If this is inside an optional, it should disable the optional and
everything inside it. However, we had an off by one error that made it
so that if something failed to resolve in the call 1 pass, then it would
disable the optional but not any of the statements inside it. So you if
you had the following:

  (optional opt
    (type t1)
    (call does_not_exist (...)))

then you could still resolve to t1 even though the optional was
disabled. And because t1 was in a disabled optional, it was never
written to the binary, which cause binary creation to fail with a very
poor error message. This patch fixes the off by one error so that
declarations inside an optional are propertly disabled if something
fails in the first call pass.

Note that the comparison for the first call pass in cil_resolve_ast() is
correct, since even if something fails in call1 and optionals are
disabled, there is no need to do all the resets since none of the things
being reset can change in call 1 or earlier.

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
Fix typos in error strings

Fixes issue #4

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
Fix bug when blockabstract statements failed to resolve

The following will now give an error about being unable to
resolve 'dne':

    (blockabstract dne)

Signed-off-by: Yuli Khodorkovskiy <ykhodorkovskiy@tresys.com>
Fixed the source of two potential memory leaks when copying an AST.

The functions cil_copy_block() and cil_copy_macro() had been
reinitializing a just initialized symtab array.
Fixed bug in copying an AST.

When copying a macro definition, cil_copy_list() needs to create new
parameter structures instead of just pointing to the original ones.
Refactored cil_get_symtab()
Move symtab from cil_db to root ast node

Moving the symtab to the root ast node removes the requirement for using
the cil_db to get the symtab.

Since cil_db is no longer needed for many of the cil_build functions, we
can remove the argument. Because we might need the cil_db in the future,
we are making it unused rather than outright deleting.

Signed-off-by: Yuli Khodorkovskiy <ykhodorkovskiy@tresys.com>
Do not associate the object_r role with users

The object_r role is implicitly associated with all users. However, CIL
requires that roles, even object_r, must be associated with users so
that we can validate things like contexts, where users and roles are
used together. So when generating the binary policy, we set a bit for
the user/object_r role association. However, because this association is
implied, this actually caused some userspace tools to change behavior,
and in some cases break (e.g. semanage user -l). So to maintian tooling
consistency, do not explicity associate any users with object_r, and
instead rely on the implicit association existing.

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
Add policy binary and file_contexts to .gitignore

Signed-off-by: Yuli Khodorkovskiy <ykhodorkovskiy@tresys.com>
Cleanup unused symtab_datum from disabled optionals

Children of optional AST nodes are no longer disabled by using a
'disabled' state. The children of a disabled optional are instead
completely removed from the AST. If the symtab_datum the node was pointing to
has no more AST nodes in its node list, then the datum is destroyed.

Removed state flag from symtab_datums. Optionals will now keep track if
they are disabled or enabled.

Add an fqn member to cil_symtab_datum. This allows for symtab lookups to
work properly when destroying symtabs because the fqn is not the correct key
to use for the symtab lookups.

Move logic to remove an item from a cil_list to a helper function for
clarity.

Signed-off-by: Yuli Khodorkovskiy <ykhodorkovskiy@tresys.com>
Changed how root node of the AST is initialized.

The root node cannot be initialized in cil_tree_init() because that
function is used to initialize other trees (such as argument lists)
that do not need symbol tables. So just call cil_root_init() directly
from cil_db_init().

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Small fix to cil_list_remove()

If the item at the end of the list is being removed, then the
tail pointer must be updated.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Fixed two bugs in cil_copy_ast.c

When copying a call, set the macro pointer of the new call to the
macro definition of the original call.

When copying a macro definition, do not attempt to copy the list of
parameters if there are no parameters.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Reimplemented the code to fully qualify names.

The qualified name will be based on which block's symtab the datum
is in rather than on the location of the node where the datum is
declared.

This changes how declarations in macros have their names qualified.
Before their names were qualified based on where the macro was called,
but now they are qualified based on where the macro is defined.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Changed how datums are handled when destroying a tree.

This change adds a pointer in the datum to its symtab.

When a node containing a datum is destroyed, its node will be
removed from the datum's node list. If the node list is now
empty, then the node list is destroyed and the datum is removed
from the symtab (if the symtab has not been destroyed already).

When destroying a symtab, each datum in the symtab will have its
symtab pointer set to NULL.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Refactored the name resolution code

If the name contains a ".", then
  If it contains a leading ".", then start with the root symtab.
  Otherwise, search for the first block name (which is from the
    start of the name to the first ".") in the symtabs of the
    ancestors of the node (following the parent pointers) until
    either the first block name is found or the root symtab has been
    searched unsuccessfully.
  Continue searching for block names (a "." marks the end of one block
    name and the start of the next) using the symtab of the block
    previously found until only the last component of the name is left.
  Use the symtab of the last block found to find the datum associated
    with the final component of the name.
If the name does not contain a ".", then
  Search for the name in symtabs of the ancestors of the node until
    either the datum is found or the root symtab has been searched.

A few nodes have multiple ancestors. Here is how they are searched.
In all cases, the root symtab is searched last.

blockinherit:
  First, search the ancestors of the blockinherit's parent
  Then, search the ancestors of the original block

macro call:
  First, search the call's arguments
  Then, search the ancestors of the macro declaration
  Finally, search the ancestors of the call's parent

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Added several new test policies

blockinherit_test.cil    - Test blockinherit order dependence
block_test.cil           - Test difference between inheriting blocks
                           and calling macros
macro_test.cil           - Test that declarations in macros are given
                           correct qualified name
minimum.cil              - Minimum CIL policy
name_resolution_test.cil - Test general name resolution
optional_test.cil        - Test correct handling of declaration in
                           optional that is removed

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>