The following code examples should give you a clue on using
fileassoc for your purposes.
First, we'll begin with registering a new id. We need to do that to save a slot for private data storage with each mount and/or file:
fileassoc_t myhook_id;
int error;
error = fileassoc_register("my_hook", myhook_cleanup, &myhook_id);
if (error != 0)
...handle error...
In the above example we pass a
myhook_cleanup() routine. It could look something like this:
void
myhook_cleanup(void *data)
{
printf("Myhook: Removing entry for file.\n");
...handle file entry removal...
free(data, M_TEMP);
}
Another useful thing would be to add our private data to a file. For example, let's assume we keep a custom ACL with each file:
int
myhook_acl_add(struct vnode *vp, struct myhook_acl *acl)
{
int error;
error = fileassoc_add(vp, myhook_id, acl);
if (error) {
printf("Myhook: Could not add ACL.\n");
...handle error...
}
printf("Myhook: Added ACL.\n");
return (0);
}
Adding an entry will override any entry that previously exists.
Whatever your plug is, eventually you'll want to access the private data you store with each file. To do that you can use the following:
int
myhook_acl_access(struct vnode *vp, int access_flags)
{
struct myhook_acl *acl;
acl = fileassoc_lookup(vp, myhook_id);
if (acl == NULL)
return (0);
error = myhook_acl_eval(acl, access_flags);
if (error) {
printf("Myhook: Denying access based on ACL decision.\n");
return (error);
}
return (0);
}
And, in some cases, it may be desired to remove private data associated with an file:
int error;
error = fileassoc_clear(vp, myhook_id);
if (error) {
printf("Myhook: Error occurred during fileassoc removal.\n");
...handle error...
}
As mentioned previously, the call to
fileassoc_clear() will result in a call to the “cleanup routine” specified in the initial call to
fileassoc_register().
The above should be enough to get you started.
For example usage of
fileassoc, see the Veriexec code.