/*
* 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
*/
/*
*/
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <libcontract.h>
#include <libcontract_priv.h>
#include <stdio.h>
#include <stropts.h>
#include <unistd.h>
#include <wait.h>
#include <zone.h>
#include "libnetcfg.h"
#include "libnetcfg_impl.h"
/*
* Functions to handle db interactions across zones. These functions were
* originally implemented in dlmgmtd; they were moved into this library as
* part of the merge of the ipmgmt, dlmgmt, and nwam repositories.
*/
typedef struct zopen_arg {
const char *zopen_modestr;
int zopen_oflag;
int *zopen_pipe;
int zopen_fd;
} zopen_arg_t;
typedef struct zrename_arg {
const char *zrename_newname;
typedef union zfoparg {
} zfoparg_t;
typedef struct zfcbarg {
const char *zfarg_filename;
} zfarg_t;
/* zone file callback */
/*
* Execute an operation on filename relative to zoneid's zone root. If the
* file is in the global zone, then the zfcb() callback will simply be called
* directly. If the file is in a non-global zone, then zfcb() will be called
* both from the global zone's context, and from the non-global zone's context
* (from a fork()'ed child that has entered the non-global zone). This is
* done to allow the callback to communicate with itself if needed (e.g. to
* pass back the file descriptor of an opened file).
*/
static int
{
int ctfd;
int err;
if (zoneid != GLOBAL_ZONEID) {
/*
* We need to access a file that isn't in the global zone,
* and we are running in the global zone. Accessing non-
* global zone files from the global zone is unsafe (due to
* symlink attacks); we'll need to fork a child that enters
* the zone in question and executes the callback that will
* operate on the file.
*
* Before we proceed with this zone tango, we need to create
* a new process contract for the child, as required by
* zone_enter().
*/
errno = 0;
if (ctfd == -1)
return (errno);
return (err);
}
switch (childpid) {
case -1:
(void) ct_tmpl_clear(ctfd);
return (err);
case 0:
(void) ct_tmpl_clear(ctfd);
/*
* Elevate our privileges as zone_enter() requires all
* privileges.
*/
if ((err = netcfg_elevate_privileges()) != 0)
if ((err = netcfg_drop_privileges()) != 0)
break;
default:
ct = -1;
(void) ct_tmpl_clear(ctfd);
(void) contract_abandon_id(ct);
return (errno);
}
(void) contract_abandon_id(ct);
}
}
if (!zfarg.zfarg_inglobalzone)
return (err);
}
/*
* Determine the PERMITTED privilege set and elevate privileges to that set.
* This is used in for open(), rename() and unlink() relative to the zoneid
* calls after zone_enter(). We cannot use netcfg_elevate_privileges() here
* because it tries to add the "zone" privileges which is "all" privileges
* since we are in the global zone. However, setppriv() fails because the
* zone does not have "all" privileges in its PERMITTED set.
*/
static int
{
int err = 0;
return (errno);
goto done;
}
done:
return (err);
}
static int
{
int oflags;
int err;
/*
* If the caller just wants to open() the file, the oflags and mode
* args were passed in directly. For fopen(), we were passed a
* modestr that is used to set oflags and mode. In the latter case,
* we assume modestr is either 'r' or 'w'; i.e. we only ever open a
* file for reading or writing, not both.
*/
} else {
}
/* Open the file if we're in the same zone as the file. */
if (inglobalzone == finglobalzone) {
/*
* First determine if we will be creating the file as part of
* opening it. If so, then we'll need to ensure that it has
* the proper ownership after having opened it.
*/
if ((err = netcfg_elevate_permitted_privileges()) != 0)
return (err);
} else {
(void) netcfg_drop_privileges();
return (errno);
}
}
}
if (fd < 0) {
(void) netcfg_drop_privileges();
return (err);
}
if (newfile) {
(void) netcfg_drop_privileges();
return (err);
}
}
(void) netcfg_drop_privileges();
}
/*
* If we're not in the global zone, send the file-descriptor back to
* our parent in the global zone.
*/
if (!inglobalzone) {
}
/*
* At this point, we know we're in the global zone. If the file was
* in a non-global zone, receive the file-descriptor from our child in
* the non-global zone.
*/
if (!finglobalzone) {
return (errno);
}
}
/* Parfait_ALLOW file-desc-leak fd is passed back to parent */
return (0);
}
static int
{
int err = 0;
return (0);
if ((err = netcfg_elevate_permitted_privileges()) == 0) {
(void) netcfg_drop_privileges();
}
return (err);
}
static int
{
int err = 0;
return (0);
if ((err = netcfg_elevate_permitted_privileges()) == 0) {
(void) netcfg_drop_privileges();
}
return (err);
}
static int
{
int p[2];
int err;
return (errno);
if (zoneid != GLOBAL_ZONEID) {
(void) close(p[0]);
(void) close(p[1]);
}
return (err);
}
/*
* Same as open(2), except that it opens the file relative to zoneid's zone
* root.
*/
int
int *err)
{
}
/*
* Same as fopen(3C), except that it opens the file relative to zoneid's zone
* root.
*/
FILE *
int *err)
{
if (*err != 0)
return (NULL);
}
return (fp);
}
/*
* Same as rename(2), except that old and new are relative to zoneid's zone
* root.
*/
int
{
}
/*
* Same as unlink(2), except that filename is relative to zoneid's zone root.
*/
int
{
}