tlabel.c revision e071b5fba24bf7b3147969da51eb5d194a13dcaa
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/pathname.h>
#include <nfs/nfs_clnt.h>
static kmem_cache_t *tslabel_cache;
/*
* Initialize labels infrastructure.
* This is called during startup() time (before vfs_mntroot) by thread_init().
* It has to be called early so that the is_system_labeled() function returns
* the right value when called by the networking code on a diskless boot.
*/
void
label_init(void)
{
/*
* Use the value of "label_services" within the edition module.
* If for some reason label_services is not found, this will
* result in the appropriate default -- "off."
*/
sys_labeling = 1;
else
sys_labeling = 0;
}
/*
* Allocate new ts_label_t.
*/
{
else
}
return (lab);
}
/*
* Put a hold on a label structure.
*/
void
{
}
/*
* Release previous hold on a label structure. Free it if refcnt == 0.
*/
void
{
}
{
}
{
}
/*
* Compare labels. Return 1 if equal, 0 otherwise.
*/
{
}
/*
* There's no protocol today to obtain the label from the server.
* So we rely on conventions: zones, zone names, and zone paths
* must match across TX servers and their TX clients. Now use
* the exported name to find the equivalent local zone and its
* label. Caller is responsible for doing a label_rele of the
* returned ts_label.
*/
{
return (NULL); /* error */
if (respath)
respath++; /* skip over ":" */
if (*respath != '/') {
/* treat path as absolute but it doesn't have leading '/' */
}
if (reszone == global_zone) {
return (l_admin_low);
}
/*
*/
if (treat_abs)
respath--; /* no leading '/' to skip */
if (new_reszone != global_zone) {
} else {
}
}
return (reszone->zone_slabel);
}
static ts_label_t *
{
tsol_tpc_t *tp;
int addr_type;
void *ipaddr;
struct knetconfig *knconf;
/* LINTED: following cast to ipaddr is OK */
/* LINTED: following cast to ipaddr is OK */
} else {
goto errout;
}
goto errout;
return (getflabel_cipso(vfsp));
}
goto errout;
return (srv_label);
return (NULL);
}
/*
* getflabel -
*
* Return pointer to the ts_label associated with the specified file,
* or returns NULL if error occurs. Caller is responsible for doing
* a label_rele of the ts_label.
*/
{
ts_label_t *zl;
char vpath[MAXPATHLEN];
return (NULL);
/*
* Traverse lofs mounts and fattach'es to get the real vnode
*/
/* Go elsewhere to handle all nfs files. */
return (getflabel_nfs(rvfsp));
/*
* Fast path, for objects in a labeled zone: everything except
*/
"lofs") != 0)) {
goto zone_out; /* return this label */
}
}
return (NULL);
}
/*
* Sanity check - vpath may be weird for some cases, like devices.
*/
if (*vpath != '/') {
goto zone_out;
}
/*
* If a mountpoint exists, hold the vfs while we reference it.
* Otherwise if mountpoint is NULL it should not be held (e.g.,
* and panic.)
*/
}
/*
* If the vnode source zone is properly set to a non-global zone, or
* any zone if the mount is R/W, then use the label of that zone.
*/
goto zone_out; /* return this label */
/*
* Otherwise, if we're not in the global zone, use the label of
* our zone.
*/
goto zone_out; /* return this label */
}
/*
* We're in the global zone and the mount is R/W ... so the file
* may actually be in the global zone -- or in the root of any zone.
* Always build our own path for the file, to be sure it's simplified
* (i.e., no ".", "..", "//", and so on).
*/
char *mntpt;
/*
* File is in the global zone - check whether it's admin_high.
* If it's in a filesys that was exported from the global zone,
* it's admin_low by definition. Otherwise, if it's in a
* filesys that's NOT exported to any zone, it's admin_high.
*
* And for these files if there wasn't a valid mount resource,
* the file must be admin_high (not exported, probably a global
* zone device).
*/
if (!vfs_is_held)
goto out_high;
if (to_zone != global_zone) {
/* force admin_low */
}
}
if (mntpt_ref)
if (!exported) {
const char *rstr;
/*
* Check for a match: does this vfs correspond
* to our global zone file path? I.e., check
* if the resource string of this vfs is a
* prefix of our path.
*/
/* force admin_low */
break;
}
}
}
if (!exported)
goto out_high;
}
if (vfs_is_held)
/*
* Now that we have the "home" zone for the file, return the slabel
* of that zone.
*/
label_hold(zl);
return (zl);
if (vfs_is_held)
return (l_admin_high);
}
static int
{
int error = 0;
return (EIO);
sizeof (*(label_p))) != 0)
return (error);
}
/*
* fgetlabel(2TSOL) - get file label
* getlabel(2TSOL) - get file label
*/
int
{
char *spath;
int error;
/* Sanity check arguments */
}
}
if (error != 0)
else
return (0);
}
int
{
int error;
if (error != 0)
else
return (0);
}
/*
* Used by NFSv4 to query label of a pathname
*/
{
char path[MAXNAMELEN];
/*
* mount traverse has been done by caller
* before calling this routine.
*/
} else {
/*
* v_path not cached. Since we rely on path
* of an obj to get its label, we need to get
* path corresponding to the parent vnode.
*/
do {
return (NULL);
}
/*
* Caller has verified that the file is either
* exported or visible. So if the path falls in
* global zone, admin_low is returned; otherwise
* the zone's label is returned.
*/
return (zone_label);
}