Properly permission check cache_inode_remove

For mode, remove requires rwx on the directory, and if S_IVTX (sticky
bit) is set, the user must own the parent directory or the target.

For ACL, things are much more complicated.

Though the spec doesn't seem to require ACE4_LIST_DIR or ACE4_EXECUTE,
I believe those permissions are necessary to properly permission check
remove when some filesystem (such as GPFS) has converted mode bits
into an ACL.

Section 6.2.1.3.2. ACE4_DELETE vs. ACE4_DELETE_CHILD of RFC 3530 bis has
an extensive description of how permission checking for remove should
occur, however, I think it is still not quite right. Things also get
a bit interesting if the parent directory has an ACL and the file only
has a mode, or visa versa. These situations can easily be resolved
however by simple logic.

There are some Rationale: sections below. Please note them, they reflect
conditions that are not implied by RFC 3530bis.

The complete order of permission checking is as follows. Evaluation
of these steps ends when a step indicates the operation is allowed or
denied.

1. Check for basic delete permission in the parent directory. This is
   done by checking for rwx mode or LIST_DIR | EXECUTE | DELETE_CHILD.

   Rationale: Linux seems to require rwx to unlink a file despite the
   documentation for unlink indicating only wx is necessary. The
   requirement for rx (LIST_DIR | EXECUTE (or SEARCH) in ACL parlance)
   for ACLs is a simple extension of this. Note that NFS v4 ACL
   effectively splits w permission for directories into ADD_FILE and
   DELETE_CHILD.

   The result of this permission check is saved for later use.

2. If check 1 failed, check for basic directory access (rx mode or
   LIST_DIR | EXECUTE ACL).

   Rationale: Even if the user is going to be allowed to delete the
   target based on ACE4_DELETE being allowed by the target's ACL, the
   user should still be allowed to see the target inode in the parent
   directory.

   If this check fails, the operation is denied.

3. At this point we know the user is allowed to look at the target...

4. If check 1 passed and the sticky bit is not set, the operation is
   allowed. If the sticky bit is set and the user owns the parent
   directory or the target, the operation is allowed.

5. Check for ACE4_DELETE on the target.

   NOTE: The sticky bit is ignored in this case.

   Rationale: if the file owner has explicitly given ACE4_DELETE to a
   user, that user should be able to delete the file. ACE4_DELETE is not
   typically granted in conversion of mode bits to ACL and is unlikely
   to be present in the inherited ACL of a sticky directory (such as
   an implementation of a /tmp style directory - at least not for
   non owners - a /tmp style directory could be implemented with
   ACLs and inheritance without the sticky bit by allowing ADD_FILE
   for the directory and havign an inherited ACL that grants the owner
   ACE4_DELETE).

   NOTE: This check specifically checks if the access check allowed
   ACE4_DELETE because it has an empty mode check, which will always
   succeed.

   If this check succeeds because ACE4_DELETE was allowed the
   operation is allowed. If this check fails, the operation is
   denied.

6. If the sticky bit is set and the user doesn't own the parent
   directory AND doesn't own the target, the operation is denied.

7. If check 1 failed because mode bits wx were not allowed, the
   operation is denied.

8. If check 1 failed because ACE4_DELETE_CHILD was explicitly
   denied, the operation is denied.

9. Now we can check the special case documented in Section
   6.2.1.3.2. ACE4_DELETE vs. ACE4_DELETE_CHILD of RFC 3530 bis.
   Check if the parent directory allows ADD_FILE | LIST_DIR | EXECUTE.

   Rationale: LIST_DIR | EXECUTE is required for this check for the same
   reason as in the other checks. This special case handles a situation
   where a server may have done a simplistic conversion of rwx mode
   permission to an ACL.

   If this test passes, the operation is allowed otherwise the operation
   is denied.

Signed-off-by: Frank S. Filz <ffilz@us.ibm.com>