Blame doc/libacl.txt

rpm-build 0a0c83
Internals of the libacl library
rpm-build 0a0c83
===============================
rpm-build 0a0c83
rpm-build 0a0c83
Posix 1003.1e DS17 leaves the library developer relatively few choices
rpm-build 0a0c83
on how to  implement the  library. A  pseudo object  oriented approach
rpm-build 0a0c83
seems necessary (otherwise, not all of the  requirements can  be met).
rpm-build 0a0c83
Unfortunately, C is no object oriented language,  so the  classes etc.
rpm-build 0a0c83
need to be hand coded. Here is how it works. 
rpm-build 0a0c83
rpm-build 0a0c83
From the user's point of view, the following things are objects:
rpm-build 0a0c83
rpm-build 0a0c83
  F - acl_t objects
rpm-build 0a0c83
    - acl_entry_t objects
rpm-build 0a0c83
    - acl_permset_t objects
rpm-build 0a0c83
  F - strings returned by acl_to_text
rpm-build 0a0c83
  F - entities returned by acl_get_qualifier
rpm-build 0a0c83
rpm-build 0a0c83
The objects flagged with F need to be freed with acl_free()  when they
rpm-build 0a0c83
are no longer needed. 
rpm-build 0a0c83
rpm-build 0a0c83
The user gets pointers to the contents of  these objects.  Each object
rpm-build 0a0c83
also has a prefix, which is not accessible from the user. The complete
rpm-build 0a0c83
objects  are  declared  in  <lib/libacl.h>. The  p_magic field  of the
rpm-build 0a0c83
prefix is set to <object_name>_MAGIC. 
rpm-build 0a0c83
rpm-build 0a0c83
The macros ext2int() and  int2ext() convert  between the  internal and
rpm-build 0a0c83
external view on objects. The  macros new_obj_p()  and new_var_obj_p()
rpm-build 0a0c83
create a new object and object with  variable size,  respectively. See
rpm-build 0a0c83
the code for the rest. 
rpm-build 0a0c83
rpm-build 0a0c83
The code necessary to access fields in objects, especially  in objects
rpm-build 0a0c83
accessed through indirections, would get almost unreadable. The second
rpm-build 0a0c83
ACL entry of an ACL would be: 
rpm-build 0a0c83
rpm-build 0a0c83
  acl_obj *acl_p;
rpm-build 0a0c83
  acl_entry_obj *acl_entry_p = acl_p->i.a_ring->i.e_next;
rpm-build 0a0c83
rpm-build 0a0c83
For  better  readability,  all the  "i.a_", "i.e_"  etc. parts  can be
rpm-build 0a0c83
hidden using macros: 
rpm-build 0a0c83
rpm-build 0a0c83
  acl_obj *acl_p;
rpm-build 0a0c83
  acl_entry_obj *acl_entry_p = acl_p->aring->enext;
rpm-build 0a0c83
rpm-build 0a0c83
rpm-build 0a0c83
ACLs and ACL entries
rpm-build 0a0c83
====================
rpm-build 0a0c83
The ACL entries associated with an ACL are stored  on a  sorted double
rpm-build 0a0c83
linked list. The first and last entries in that list are available via
rpm-build 0a0c83
ACL object. This is implemented with a little trick: 
rpm-build 0a0c83
  
rpm-build 0a0c83
  The  acl_obj  and  acl_entry_obj  have  {a,e}_prev  and {a,e}_prev
rpm-build 0a0c83
  pointers at the same  memory location  (directly after  the object
rpm-build 0a0c83
  prefix).  The  a_prev  and  a_next  entries  of  an   acl_obj  are
rpm-build 0a0c83
  initialized to point to the acl_obj itself  (this requires  a type
rpm-build 0a0c83
  cast).  We  only  need  to check  if the  acl_obj object  has been
rpm-build 0a0c83
  reached to detect the end of  the list.  Since the  acl_obj object
rpm-build 0a0c83
  isn't actually an acl_entry_obj object, care must be taken  not to
rpm-build 0a0c83
  manipulate any of the other acl_entry_obj fields other than e_prev
rpm-build 0a0c83
  and e_next. 
rpm-build 0a0c83
rpm-build 0a0c83
Whenever  an  entry  is  changed,  __acl_reorder_obj_p()  reorders the
rpm-build 0a0c83
entries  accordingly. This  takes O(n^2)  time, but  that's not  a big
rpm-build 0a0c83
problem as long as ACLs don't contain very many  entries. Some  of the
rpm-build 0a0c83
library  functions  need a  sorted ACL  anyway, so  the best  we could
rpm-build 0a0c83
possibly do is  O(n*log(n)), with  a sorted  flag in  each ACL,  and a
rpm-build 0a0c83
complicated  sorting  function  (the  linked  list  would  have  to be
rpm-build 0a0c83
converted to an array first to allow more efficient sorting). 
rpm-build 0a0c83
rpm-build 0a0c83
rpm-build 0a0c83
Hope that helps. Good luck!
rpm-build 0a0c83
rpm-build 0a0c83
Andreas
rpm-build 0a0c83