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