347 lines
8.9 KiB
Groff
347 lines
8.9 KiB
Groff
.\" $NetBSD: fileassoc.9,v 1.30 2017/07/03 21:28:48 wiz Exp $
|
|
.\"
|
|
.\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. The name of the author may not be used to endorse or promote products
|
|
.\" derived from this software without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd December 1, 2016
|
|
.Dt FILEASSOC 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm fileassoc
|
|
.Nd in-kernel, file system independent, file meta-data association
|
|
.Sh SYNOPSIS
|
|
.In sys/fileassoc.h
|
|
.Ft int
|
|
.Fn fileassoc_register "const char *name" \
|
|
"fileassoc_cleanup_cb_t cleanup_cb" "fileassoc_t *result"
|
|
.Ft int
|
|
.Fn fileassoc_deregister "fileassoc_t id"
|
|
.Ft void *
|
|
.Fn fileassoc_lookup "struct vnode *vp" "fileassoc_t id"
|
|
.Ft int
|
|
.Fn fileassoc_table_delete "struct mount *mp"
|
|
.Ft int
|
|
.Fn fileassoc_table_clear "struct mount *mp" "fileassoc_t id"
|
|
.Ft int
|
|
.Fn fileassoc_table_run "struct mount *mp" "fileassoc_t id" \
|
|
"fileassoc_cb_t cb" "void *cookie"
|
|
.Ft int
|
|
.Fn fileassoc_file_delete "struct vnode *vp"
|
|
.Ft int
|
|
.Fn fileassoc_add "struct vnode *vp" "fileassoc_t id" "void *data"
|
|
.Ft int
|
|
.Fn fileassoc_clear "struct vnode *vp" "fileassoc_t id"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm
|
|
KPI allows association of meta-data with files independent of file system
|
|
support for such elaborate meta-data.
|
|
.Pp
|
|
When plugging a new fileassoc to the system, a developer can specify private
|
|
data to be associated with every file, as well as (potentially different)
|
|
private data to be associated with every file system mount.
|
|
.Pp
|
|
For example, a developer might choose to associate a custom ACL with every
|
|
file, and a count of total files with ACLs with the mount.
|
|
.Sh KERNEL PROGRAMMING INTERFACE
|
|
Designed with simplicity in mind, the
|
|
.Nm
|
|
KPI usually accepts four different types of parameters to the most commonly
|
|
used routines:
|
|
.Bl -tag -width "123456"
|
|
.It Ft struct mount * Ar mp
|
|
Describing a mount on which to take action.
|
|
.It Ft struct vnode * Ar vp
|
|
Describing a file on which to take action.
|
|
.It Ft fileassoc_t Ar id
|
|
Describing an id, as returned from a successful call to
|
|
.Fn fileassoc_register .
|
|
.It Ft void * Ar data
|
|
Describing a custom private data block, attached to either a file or a mount.
|
|
.El
|
|
.Pp
|
|
Before using the
|
|
.Nm
|
|
KPI it is important to keep in mind that the interface provides memory
|
|
management only for
|
|
.Nm
|
|
internal memory.
|
|
Any additional memory stored in the tables (such as private data structures
|
|
used by custom fileassocs) should be allocated and freed by the developer.
|
|
.Pp
|
|
.Nm
|
|
provides the ability to specify a
|
|
.Dq cleanup
|
|
routine to
|
|
.Fn fileassoc_register
|
|
(see below)
|
|
to be called whenever an entry for a file or a mount is deleted.
|
|
.Ss REGISTRATION AND DEREGISTRATION ROUTINES
|
|
These routines allow a developer to allocate a
|
|
.Nm
|
|
slot to be used for private data.
|
|
.Bl -tag -width "123456"
|
|
.It Fn fileassoc_register "name" "cleanup_cb" "result"
|
|
Registers a new fileassoc as
|
|
.Ar name ,
|
|
and returns a
|
|
.Ft fileassoc_t
|
|
via
|
|
.Fa result
|
|
to be used as identifier in subsequent calls to the
|
|
.Nm
|
|
subsystem.
|
|
.Pp
|
|
.Fn fileassoc_register
|
|
returns zero on success.
|
|
Otherwise, an error number will be returned.
|
|
.Pp
|
|
If
|
|
.Ar cleanup_cb
|
|
is not
|
|
.Dv NULL ,
|
|
it will be called during delete/clear operations (see routines below) with
|
|
indication whether the passed data is file- or mount-specific.
|
|
.Pp
|
|
.Ar cleanup_cb
|
|
should be a function receiving a
|
|
.Ft void *
|
|
and returning
|
|
.Ft void .
|
|
See the
|
|
.Sx EXAMPLES
|
|
section for illustration.
|
|
.Pp
|
|
.It Fn fileassoc_deregister "id"
|
|
Deregisters a
|
|
.Nm fileassoc
|
|
whose id is
|
|
.Ar id .
|
|
.Pp
|
|
Note that calling
|
|
.Fn fileassoc_deregister
|
|
only frees the associated slot in the
|
|
.Nm
|
|
subsystem.
|
|
It is up to the developer to take care of garbage collection.
|
|
.El
|
|
.Ss LOOKUP ROUTINES
|
|
These routines allow lookup of
|
|
.Nm
|
|
mounts, files, and private data attached to them.
|
|
.Bl -tag -width "123456"
|
|
.It Fn fileassoc_lookup "vp" "id"
|
|
Returns the private data for the file/id combination
|
|
or
|
|
.Dv NULL
|
|
if not found.
|
|
.El
|
|
.Ss MOUNT-WIDE ROUTINES
|
|
.Bl -tag -width "123456"
|
|
.It Fn fileassoc_table_delete "mp"
|
|
Deletes a fileassoc table for
|
|
.Ar mp .
|
|
.Pp
|
|
.It Fn fileassoc_table_clear "mp" "id"
|
|
Clear all table entries for
|
|
.Ar fileassoc
|
|
from
|
|
.Ar mp .
|
|
.Pp
|
|
If specified, the fileassoc's
|
|
.Dq cleanup routine
|
|
will be called with a pointer to the private data structure.
|
|
.Pp
|
|
.It Fn fileassoc_table_run "mp" "id" "cb" "cookie"
|
|
For each entry for
|
|
.Ar id ,
|
|
call
|
|
.Ar cb
|
|
with the entry being the first argument, and
|
|
.Ar cookie
|
|
being the second argument.
|
|
.Pp
|
|
.Ar cb
|
|
is a function returning
|
|
.Ft void
|
|
and receiving two
|
|
.Ft "void *"
|
|
parameters.
|
|
.El
|
|
.Ss FILE-SPECIFIC ROUTINES
|
|
.Bl -tag -width "123456"
|
|
.It Fn fileassoc_file_delete "vp"
|
|
Delete the fileassoc entries for
|
|
.Ar vp .
|
|
.Pp
|
|
If specified, the
|
|
.Dq cleanup routines
|
|
of all fileassoc types added will be called with a pointer to the corresponding
|
|
private data structure and indication of
|
|
.Dv FILEASSOC_CLEANUP_FILE .
|
|
.El
|
|
.Ss FILEASSOC-SPECIFIC ROUTINES
|
|
.Bl -tag -width "123456"
|
|
.It Fn fileassoc_add "vp" "id" "data"
|
|
Add private data in
|
|
.Ar data
|
|
for
|
|
.Ar vp ,
|
|
for the fileassoc specified by
|
|
.Ar id .
|
|
.Pp
|
|
If a table for the mount-point
|
|
.Ar vp
|
|
is on doesn't exist, one will be created automatically.
|
|
.Nm
|
|
manages internally the optimal table sizes as tables are modified.
|
|
.It Fn fileassoc_clear "vp" "id"
|
|
Clear the private data for
|
|
.Ar vp ,
|
|
for the fileassoc specified by
|
|
.Ar id .
|
|
.Pp
|
|
If specified, the fileassoc's
|
|
.Dq cleanup routine
|
|
will be called with a pointer to the private data structure and indication of
|
|
.Dv FILEASSOC_CLEANUP_FILE .
|
|
.El
|
|
.Sh EXAMPLES
|
|
The following code examples should give you a clue on using
|
|
.Nm
|
|
for your purposes.
|
|
.Pp
|
|
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:
|
|
.Bd -literal -offset indent
|
|
fileassoc_t myhook_id;
|
|
int error;
|
|
|
|
error = fileassoc_register("my_hook", myhook_cleanup, &myhook_id);
|
|
if (error != 0)
|
|
...handle error...
|
|
.Ed
|
|
.Pp
|
|
In the above example we pass a
|
|
.Fn myhook_cleanup
|
|
routine.
|
|
It could look something like this:
|
|
.Bd -literal -offset indent
|
|
void
|
|
myhook_cleanup(void *data)
|
|
{
|
|
|
|
printf("Myhook: Removing entry for file.\en");
|
|
...handle file entry removal...
|
|
free(data, M_TEMP);
|
|
}
|
|
.Ed
|
|
.Pp
|
|
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:
|
|
.Bd -literal -offset indent
|
|
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.\en");
|
|
...handle error...
|
|
}
|
|
|
|
printf("Myhook: Added ACL.\en");
|
|
|
|
return (0);
|
|
}
|
|
.Ed
|
|
.Pp
|
|
Adding an entry will override any entry that previously exists.
|
|
.Pp
|
|
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:
|
|
.Bd -literal -offset indent
|
|
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.\en");
|
|
return (error);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
.Ed
|
|
.Pp
|
|
And, in some cases, it may be desired to remove private data associated with
|
|
an file:
|
|
.Bd -literal -offset indent
|
|
int error;
|
|
|
|
error = fileassoc_clear(vp, myhook_id);
|
|
if (error) {
|
|
printf("Myhook: Error occurred during fileassoc removal.\en");
|
|
...handle error...
|
|
}
|
|
.Ed
|
|
.Pp
|
|
As mentioned previously, the call to
|
|
.Fn fileassoc_clear
|
|
will result in a call to the
|
|
.Dq cleanup routine
|
|
specified in the initial call to
|
|
.Fn fileassoc_register .
|
|
.Pp
|
|
The above should be enough to get you started.
|
|
.Pp
|
|
For example usage of
|
|
.Nm ,
|
|
see the Veriexec code.
|
|
.Sh CODE REFERENCES
|
|
The
|
|
.Nm
|
|
is implemented within
|
|
.Pa src/sys/kern/kern_fileassoc.c .
|
|
.Sh SEE ALSO
|
|
.Xr veriexec 9
|
|
.Sh HISTORY
|
|
The
|
|
.Nm
|
|
KPI first appeared in
|
|
.Nx 4.0 .
|
|
.Sh AUTHORS
|
|
.An Elad Efrat Aq Mt elad@NetBSD.org
|
|
.An Brett Lymn Aq Mt blymn@NetBSD.org
|