567 lines
17 KiB
Groff
567 lines
17 KiB
Groff
.\" $NetBSD: kauth.9,v 1.4 2006/05/28 06:50:37 yamt Exp $
|
|
.\"
|
|
.\" Copyright (c) 2005, 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. All advertising materials mentioning features or use of this software
|
|
.\" must display the following acknowledgement:
|
|
.\" This product includes software developed by Elad Efrat.
|
|
.\" 4. 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 May 28, 2006
|
|
.Dt KAUTH 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm kauth
|
|
.Nd kernel authorization framework
|
|
.Sh SYNOPSIS
|
|
.In sys/kauth.h
|
|
.Sh DESCRIPTION
|
|
.Nm ,
|
|
or kernel authorization, is the subsystem managing all authorization requests
|
|
inside the kernel.
|
|
It manages user credentials and rights, and can be used
|
|
to implement a system-wide security policy.
|
|
It allows external modules to plug-in the authorization process.
|
|
.Pp
|
|
.Nm
|
|
introduces some new concepts, namely
|
|
.Dq scopes
|
|
and
|
|
.Dq listeners ,
|
|
which will be detailed together with other useful information for kernel
|
|
developers in this document.
|
|
.Sh TYPES
|
|
Some
|
|
.Nm
|
|
types include the following:
|
|
.Bl -tag -width "123456"
|
|
.It kauth_cred_t
|
|
Representing credentials that can be associated with an object.
|
|
Includes user- and group-ids (real, effective, and save) as well as group
|
|
membership information.
|
|
.It kauth_scope_t
|
|
Describes a scope.
|
|
.It kauth_listener_t
|
|
Describes a listener.
|
|
.El
|
|
.Ss Terminology
|
|
.Nm
|
|
operates in various
|
|
.Dq scopes ,
|
|
each scope holding a group of
|
|
.Dq listeners .
|
|
.Pp
|
|
Each listener works as a callback for when an authorization request within the
|
|
scope is made.
|
|
When such a request is made, all listeners on the scope are passed common
|
|
information such as the credentials of the request context, an identifier for
|
|
the requested operation, and possibly other information as well.
|
|
.Pp
|
|
Every listener examines the passed information and returns its decision
|
|
regarding the requested operation.
|
|
It can either allow, deny, or defer the operation -- in which case, the
|
|
decision is left to the other listeners.
|
|
.Pp
|
|
For an operation to be allowed, all listeners must not return any deny
|
|
or defer decisions.
|
|
.Pp
|
|
Scopes manage listeners that operate in the same aspect of the system.
|
|
.Ss Kernel Programming Interface
|
|
.Nm
|
|
exports a KPI that allows developers both of
|
|
.Nx
|
|
and third-party products to authorize requests, access and modify credentials,
|
|
create and remove scopes and listeners, and perform other miscellaneous operations on
|
|
credentials.
|
|
.Ss Authorization Requests
|
|
.Nm
|
|
provides a single authorization request routine, which all authorization
|
|
requests go through.
|
|
This routine dispatches the request to the listeners of the appropriate scope,
|
|
together with four optional user-data variables, and returns the augmented
|
|
result.
|
|
.Pp
|
|
It is declared as
|
|
.Pp
|
|
.Ft int Fn kauth_authorize_action "kauth_scope_t scope" "kauth_cred_t cred" \
|
|
"kauth_action_t op" "void *arg0" "void *arg1" "void *arg2" "void *arg3"
|
|
.Pp
|
|
An authorization request can return one of two possible values.
|
|
Zero indicates success -- the operation is allowed;
|
|
.Er EPERM
|
|
(see
|
|
.Xr errno 2 )
|
|
indicates failure -- the operation is denied.
|
|
.Pp
|
|
Each scope has its own authorization wrapper, to make it easy to call from various
|
|
places by eliminating the need to specify the scope and/or cast values.
|
|
The authorization wrappers are detailed in each scope's section.
|
|
.Ss Generic Scope
|
|
The generic scope,
|
|
.Dq org.netbsd.kauth.generic ,
|
|
manages generic authorization requests in the kernel.
|
|
.Pp
|
|
The authorization wrapper for this scope is declared as
|
|
.Pp
|
|
.Ft int Fn kauth_authorize_generic "kauth_cred_t cred" "kauth_action_t op" \
|
|
"void *arg0"
|
|
.Pp
|
|
The following operations are available for this scope:
|
|
.Bl -tag -width "123456"
|
|
.It Dv KAUTH_GENERIC_ISSUSER
|
|
Checks whether the credentials belong to the super-user.
|
|
.Pp
|
|
If
|
|
.Ar arg0
|
|
is not
|
|
.Dv NULL ,
|
|
it's treated as a
|
|
.Ft u_short *
|
|
to accounting flags, and the
|
|
.Dv ACU
|
|
flag is set.
|
|
.El
|
|
.Ss Process Scope
|
|
The process scope,
|
|
.Dq org.netbsd.kauth.process ,
|
|
manages authorization requests related to processes in the system.
|
|
.Pp
|
|
The authorization wrapper for this scope is declared as
|
|
.Pp
|
|
.Ft int Fn kauth_authorize_process "kauth_cred_t cred" \
|
|
"kauth_action_t op" "struct proc *p" "void *arg1" "void *arg2" \
|
|
"void *arg3"
|
|
.Pp
|
|
The following operations are available for this scope:
|
|
.Bl -tag -width "123456"
|
|
.It Dv KAUTH_PROCESS_CANPTRACE
|
|
Checks whether an object with one set of credentials can use
|
|
.Xr ptrace 2
|
|
on another process, possibly with a different set of credentials.
|
|
.Pp
|
|
.Ar arg1
|
|
contains the credentials of the process being attached to.
|
|
.It Dv KAUTH_PROCESS_CANSIGNAL
|
|
Checks whether an object with one set of credentials can post signals
|
|
to another process.
|
|
.Pp
|
|
.Ar arg1
|
|
and
|
|
.Ar arg2
|
|
contain the credentials
|
|
.Ft ( kauth_cred_t )
|
|
and the process data
|
|
.Ft ( struct proc * )
|
|
of the process the signal is posted to, respectively.
|
|
.Ar arg3
|
|
is the signal to be posted.
|
|
.It Dv KAUTH_PROCESS_CANSEE
|
|
Checks whether an object with one set of credentials can access
|
|
information about another object, possibly with a different set of
|
|
credentials.
|
|
.Pp
|
|
.Ar arg1
|
|
contains the credentials of the process looked at.
|
|
.El
|
|
.Ss Credentials Accessors and Mutators
|
|
.Nm
|
|
has a variety of accessor and mutator routines to handle
|
|
.Ft kauth_cred_t
|
|
objects.
|
|
.Pp
|
|
The following routines can be used to access and modify the user- and
|
|
group-ids in a
|
|
.Ft kauth_cred_t :
|
|
.Bl -tag -width "123456"
|
|
.It Ft uid_t Fn kauth_cred_getuid "kauth_cred_t cred"
|
|
Returns the real user-id from
|
|
.Ar cred .
|
|
.It Ft uid_t Fn kauth_cred_geteuid "kauth_cred_t cred"
|
|
Returns the effective user-id from
|
|
.Ar cred .
|
|
.It Ft uid_t Fn kauth_cred_getsvuid "kauth_cred_t cred"
|
|
Returns the saved user-id from
|
|
.Ar cred .
|
|
.It Ft void Fn kauth_cred_setuid "kauth_cred_t cred" "uid_t uid"
|
|
Sets the real user-id in
|
|
.Ar cred
|
|
to
|
|
.Ar uid .
|
|
.It Ft void Fn kauth_cred_seteuid "kauth_cred_t cred" "uid_t uid"
|
|
Sets the effective user-id in
|
|
.Ar cred
|
|
to
|
|
.Ar uid .
|
|
.It Ft void Fn kauth_cred_setsvuid "kauth_cred_t cred" "uid_t uid"
|
|
Sets the saved user-id in
|
|
.Ar cred
|
|
to
|
|
.Ar uid .
|
|
.It Ft gid_t Fn kauth_cred_getgid "kauth_cred_t cred"
|
|
Returns the real group-id from
|
|
.Ar cred .
|
|
.It Ft gid_t Fn kauth_cred_getegid "kauth_cred_t cred"
|
|
Returns the effective group-id from
|
|
.Ar cred .
|
|
.It Ft gid_t Fn kauth_cred_getsvgid "kauth_cred_t cred"
|
|
Returns the saved group-id from
|
|
.Ar cred .
|
|
.It Ft void Fn kauth_cred_setgid "kauth_cred_t cred" "gid_t gid"
|
|
Sets the real group-id in
|
|
.Ar cred
|
|
to
|
|
.Ar gid .
|
|
.It Ft void Fn kauth_cred_setegid "kauth_cred_t cred" "gid_t gid"
|
|
Sets the effective group-id in
|
|
.Ar cred
|
|
to
|
|
.Ar gid .
|
|
.It Ft void Fn kauth_cred_setsvgid "kauth_cred_t cred" "gid_t gid"
|
|
Sets the saved group-id in
|
|
.Ar cred
|
|
to
|
|
.Ar gid .
|
|
.It Ft uint16_t Fn kauth_cred_getrefcnt "kauth_cred_t cred"
|
|
Return the reference count for
|
|
.Ar cred .
|
|
.El
|
|
.Pp
|
|
The following routines can be used to access and modify the group
|
|
list in a
|
|
.Ft kauth_cred_t :
|
|
.Bl -tag -width "123456"
|
|
.It Ft int Fn kauth_cred_ismember_gid "kauth_cred_t cred" "gid_t gid" \
|
|
"int *resultp"
|
|
Checks if the group-id
|
|
.Ar gid
|
|
is a member in the group list of
|
|
.Ar cred .
|
|
.Pp
|
|
If it is,
|
|
.Ar resultp
|
|
will be set to one, otherwise, to zero.
|
|
.Pp
|
|
The return value is an error code, or zero for success.
|
|
.It Ft uint16_t Fn kauth_cred_ngroups "kauth_cred_t cred"
|
|
Return the number of groups in the group list of
|
|
.Ar cred .
|
|
.It Ft int Fn kauth_cred_group "kauth_cred_t cred" "uint16_t idx"
|
|
Return the group-id of the group at index
|
|
.Ar idx
|
|
in the group list of
|
|
.Ar cred .
|
|
.It Ft int Fn kauth_cred_setgroups "kauth_cred_t cred" "gid_t *groups" \
|
|
"size_t ngroups" "uid_t gmuid"
|
|
Copy
|
|
.Ar ngroups
|
|
groups from array pointed to by
|
|
.Ar groups
|
|
to the group list in
|
|
.Ar cred ,
|
|
adjusting the number of groups in
|
|
.Ar cred
|
|
appropriately.
|
|
.Pp
|
|
Any groups remaining will be set to an invalid value.
|
|
.Pp
|
|
.Ar gmuid
|
|
is unused for now, and to maintain interface compatibility with the Darwin
|
|
KPI.
|
|
.It Ft int Fn kauth_cred_getgroups "kauth_cred_t cred" "gid_t *groups" \
|
|
"size_t ngroups"
|
|
Copy
|
|
.Ar ngroups
|
|
groups from the group list in
|
|
.Ar cred
|
|
to the buffer pointed to by
|
|
.Ar groups .
|
|
.Pp
|
|
The number of groups in
|
|
.Ar cred
|
|
will be returned.
|
|
.El
|
|
.Ss Credentials Inheritance and Reference Counting
|
|
.Nm
|
|
provides a KPI for handling a
|
|
.Ft kauth_cred_t
|
|
in shared credentials situations and credential inheritance.
|
|
.Pp
|
|
When a
|
|
.Ft kauth_cred_t
|
|
is first allocated, its reference count is set to 1.
|
|
However, with time, its reference count can grow as more objects (processes,
|
|
files, etc.) reference it.
|
|
One such case is during a
|
|
.Xr fork 2
|
|
where the child process inherits the credentials of the parent.
|
|
.Pp
|
|
To prevent freeing a
|
|
.Ft kauth_cred_t
|
|
while it is still referenced, the following routines are available to maintain
|
|
its reference count:
|
|
.Bl -tag -width "123456"
|
|
.It Ft void Fn kauth_cred_hold "kauth_cred_t cred"
|
|
Increases reference count to
|
|
.Ar cred
|
|
by one.
|
|
.It Ft void Fn kauth_cred_free "kauth_cred_t cred"
|
|
Decreases the reference count to
|
|
.Ar cred
|
|
by one.
|
|
.Pp
|
|
If the reference count dropped to zero, the memory used by
|
|
.Ar cred
|
|
will be returned back to the memory pool.
|
|
.El
|
|
.Ss Credentials Memory Management
|
|
Data-structures for credentials, listeners, and scopes are allocated from
|
|
memory pools managed by the
|
|
.Xr pool 9
|
|
subsystem.
|
|
.Pp
|
|
The
|
|
.Ft kauth_cred_t
|
|
objects have their own memory management routines:
|
|
.Bl -tag -width "123456"
|
|
.It Ft kauth_cred_t Fn kauth_cred_alloc "void"
|
|
Allocates a new
|
|
.Ft kauth_cred_t ,
|
|
initializes its lock, and sets its reference count to one.
|
|
.El
|
|
.Ss Conversion Routines
|
|
Sometimes it might be necessary to convert a
|
|
.Ft kauth_cred_t
|
|
to a predecessing type, such as
|
|
.Ft struct pcred
|
|
or
|
|
.Ft struct ucred ,
|
|
or convert credentials passed from userland as a
|
|
.Ft struct uucred
|
|
to a
|
|
.Ft kauth_cred_t .
|
|
.Pp
|
|
The following routines are available for these cases:
|
|
.Bl -tag -width "123456"
|
|
.It Ft void Fn kauth_cred_topcred "kauth_cred_t cred" "struct pcred *pcred"
|
|
Convert a
|
|
.Ft kauth_cred_t
|
|
to a
|
|
.Ft struct pcred .
|
|
.Pp
|
|
This includes real and saved user- and group-ids, a kernel-space pointer
|
|
to a
|
|
.Ft struct ucred
|
|
(the address of
|
|
.Ar cred
|
|
is used for this), and reference count, copied from
|
|
.Ar cred .
|
|
.It Ft void Fn kauth_cred_toucred "kauth_cred_t cred" "struct ucred *ucred"
|
|
Convert a
|
|
.Ft kauth_cred_t
|
|
to a
|
|
.Ft struct ucred .
|
|
.Pp
|
|
This includes effective user- and group-ids, number of groups, and the group
|
|
list from
|
|
.Ar cred .
|
|
.Pp
|
|
Note that
|
|
.Nm
|
|
will try to copy as many groups as
|
|
.Ar ucred
|
|
can hold.
|
|
.It Ft void Fn kauth_cred_uucvt "kauth_cred_t cred" "const struct uucred *uucred"
|
|
Convert userland's view of credentials to a
|
|
.Ft kauth_cred_t .
|
|
.Pp
|
|
This includes effective user- and group-ids, a number of groups, and a group
|
|
list.
|
|
The reference count is set to one.
|
|
.Pp
|
|
Note that
|
|
.Nm
|
|
will try to copy as many groups as can be held inside a
|
|
.Ft kauth_cred_t .
|
|
The addition of groups will also guarantee order and no duplicates.
|
|
.It Ft int Fn kauth_cred_uucmp "kauth_cred_t cred" "struct uucred *uucred"
|
|
Compares
|
|
.Ar cred
|
|
with the userland credentials in
|
|
.Ar uucred .
|
|
.Pp
|
|
Common values that will be compared are effective user- and group-ids, and
|
|
the group list.
|
|
.El
|
|
.Ss Miscellaneous Routines
|
|
Other routines provided by
|
|
.Nm
|
|
are:
|
|
.Bl -tag -width "123456"
|
|
.It Ft void Fn kauth_cred_clone "kauth_cred_t cred1" "kauth_cred_t cred2"
|
|
Clone credentials from
|
|
.Ar cred1
|
|
to
|
|
.Ar cred2 ,
|
|
except for the lock and reference count.
|
|
.Pp
|
|
.It Ft kauth_cred_t Fn kauth_cred_dup "kauth_cred_t cred"
|
|
Duplicate
|
|
.Ar cred .
|
|
.Pp
|
|
What this routine does is call
|
|
.Fn kauth_cred_alloc
|
|
followed by a call to
|
|
.Fn kauth_cred_clone .
|
|
.It Ft kauth_cred_t Fn kauth_cred_copy "kauth_cred_t cred"
|
|
Works like
|
|
.Fn kauth_cred_dup ,
|
|
except for a few differences.
|
|
.Pp
|
|
If
|
|
.Ar cred
|
|
already has a reference count of one, it will be returned.
|
|
Otherwise, a new
|
|
.Ft kauth_cred_t
|
|
will be allocated and the credentials from
|
|
.Ar cred
|
|
will be cloned to it.
|
|
Last, a call to
|
|
.Fn kauth_cred_free
|
|
for
|
|
.Ar cred
|
|
will be done.
|
|
.It Ft kauth_cred_t Fn kauth_cred_get "void"
|
|
Return the credentials associated with the current process.
|
|
.El
|
|
.Ss Scope Management
|
|
.Nm
|
|
provides routines to manage the creation and deletion of scopes on the
|
|
system.
|
|
.Pp
|
|
Note that the built-in scopes, the
|
|
.Dq generic
|
|
scope and the
|
|
.Dq process
|
|
scope, can't be deleted.
|
|
.Bl -tag -width "123456"
|
|
.It Ft kauth_scope_t Fn kauth_register_scope "const char *id" \
|
|
"kauth_scope_callback_t cb" "void *cookie"
|
|
Register a new scope on the system.
|
|
.Ar id
|
|
is the name of the scope, usually in reverse DNS-like notation.
|
|
For example,
|
|
.Dq org.netbsd.kauth.myscope .
|
|
.Ar cb
|
|
is the default listener, to which authorization requests for this scope
|
|
will be dispatched to.
|
|
.Ar cookie
|
|
is optional user-data that will be passed to all listeners
|
|
during authorization on the scope.
|
|
.It Ft void Fn kauth_deregister_scope "kauth_scope_t scope"
|
|
Deregister
|
|
.Ar scope
|
|
from the scopes available on the system.
|
|
.El
|
|
.Ss Listener Management
|
|
Listeners in
|
|
.Nm
|
|
are authorization callbacks that are called during an authorization
|
|
request in the scope which they belong to.
|
|
.Pp
|
|
When an authorization request is made, all listeners associated with
|
|
a scope are called to allow, deny, or defer the request.
|
|
.Pp
|
|
It is enough for one listener to deny the request in order for the
|
|
request to be denied; but all listeners are called during an authorization
|
|
process none-the-less.
|
|
All listeners are required to allow the request for it to be granted,
|
|
and in a case where all listeners defer the request -- leaving the decision
|
|
for other listeners -- the request is denied.
|
|
.Pp
|
|
The following KPI is provided for the management of listeners:
|
|
.Bl -tag -width "123456"
|
|
.It Ft kauth_listener_t Fn kauth_listen_scope "const char *id" \
|
|
"kauth_scope_callback_t cb" "void *cookie"
|
|
Create a new listener on the scope with the id
|
|
.Ar id ,
|
|
setting the default listener to
|
|
.Ar cb .
|
|
.\".Ar cookie
|
|
.\"is optional user-data that will be passed to the listener when called
|
|
.\"during an authorization request.
|
|
.It Ft void Fn kauth_unlisten_scope "kauth_listener_t listener"
|
|
Remove
|
|
.Ar listener
|
|
from the scope which it belongs to.
|
|
.Pp
|
|
Effectively what this does is is remove the callback from the chain of
|
|
functions to be called when an authorization request is made, preventing
|
|
from the listener from being entered in the future.
|
|
.El
|
|
.Pp
|
|
.Nm
|
|
provides no means for synchronization within listeners.
|
|
It is the the programmer's responsibility to make sure data used by the
|
|
listener is properly locked during its use, as it can be accessed
|
|
simultaneously from the same listener called multiple times.
|
|
It is also the programmer's responsibility to do garbage collection after
|
|
the listener, possibly freeing any allocated data it used.
|
|
.Pp
|
|
The common method to do the above is by having a reference count to
|
|
each listener.
|
|
On entry to the listener, this reference count should be raised, and
|
|
on exit -- lowered.
|
|
.Pp
|
|
During the removal of a listener, first
|
|
.Fn kauth_scope_unlisten
|
|
should be called to make sure the listener code will not be entered in
|
|
the future.
|
|
Then, the code should wait (possibly sleeping) until the reference count
|
|
drops to zero.
|
|
When that happens, it is safe to do the final cleanup.
|
|
.\".Sh EXAMPLES
|
|
.\" .Sh SEE ALSO
|
|
.Sh HISTORY
|
|
The kernel authorization framework first appeared in Mac OS X 10.4.
|
|
.Pp
|
|
The kernel authorization framework in
|
|
.Nx
|
|
first appeared in
|
|
.Nx 5.0 ,
|
|
and is a clean-room implementation based on Apple TN2127, available at
|
|
http://developer.apple.com/technotes/tn2005/tn2127.html
|
|
.Sh AUTHORS
|
|
.An Elad Efrat Aq elad@NetBSD.org
|
|
implemented the kernel authorization framework in
|
|
.Nx .
|
|
.Pp
|
|
.An Jason R. Thorpe Aq thorpej@NetBSD.org
|
|
provided guidance and answered questions about the Darwin implementation.
|
|
.Sh ONE MORE THING
|
|
The
|
|
.Nm
|
|
framework is dedicated to Brian Mitchell, one of the most talented people
|
|
I know.
|
|
Thanks for everything.
|