/*
* 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
* or http://www.opensolaris.org/os/licensing.
* 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 (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdlib.h>
#include <rpc/xdr.h>
#include <rpc/auth_sys.h>
#include <priv.h>
#include <xpol.h>
#include <strings.h>
/* evil knowledge of libc internals; xdr requires that the code is here */
#include "../../libc/inc/priv_private.h"
bool_t
xdr_xpol_enum(XDR *xdrs, xpol_enum *objp)
{
if (!xdr_enum(xdrs, (enum_t *)objp))
return (FALSE);
return (TRUE);
}
bool_t
xdr_xpol_uids(XDR *xdrs, xpol_uids *objp)
{
if (!xdr_uid_t(xdrs, &objp->umin))
return (FALSE);
if (!xdr_uid_t(xdrs, &objp->umax))
return (FALSE);
return (TRUE);
}
bool_t
xdr_xpol_ports(XDR *xdrs, xpol_ports *objp)
{
if (!xdr_int(xdrs, &objp->proto))
return (FALSE);
if (!xdr_uint16_t(xdrs, &objp->pmin))
return (FALSE);
if (!xdr_uint16_t(xdrs, &objp->pmax))
return (FALSE);
return (TRUE);
}
bool_t
xdr_xpol_args(XDR *xdrs, xpol_args *objp)
{
if (!xdr_xpol_enum(xdrs, &objp->xa_args_type))
return (FALSE);
switch (objp->xa_args_type) {
case XPOL_PATH:
if (!xdr_string(xdrs, &objp->xpol_args_u.xa_path, MAXPATHLEN))
return (FALSE);
break;
case XPOL_UIDS:
if (!xdr_xpol_uids(xdrs, &objp->xpol_args_u.xa_uids))
return (FALSE);
break;
case XPOL_PORTS:
if (!xdr_xpol_ports(xdrs, &objp->xpol_args_u.xa_ports))
return (FALSE);
break;
default:
return (FALSE);
}
return (TRUE);
}
#define xr_path xr_args.xpol_args_u.xa_path
#define xr_uids xr_args.xpol_args_u.xa_uids
#define xr_ports xr_args.xpol_args_u.xa_ports
/*
* When decoding, we allow any size of privilege set as required for
* core files; when encoding, we will only generate the current
* set size.
*/
bool_t
xdr_xpol_rule(XDR *xdrs, xpol_rule_t *objp)
{
xpol_rule_t *tmp_xpol_rule;
bool_t more_data = TRUE;
bool_t first_objp = TRUE;
priv_data_t *d;
uint32_t slen;
LOADPRIVDATA(d);
if (xdrs->x_op == XDR_DECODE) {
while (more_data) {
if (!xdr_u_int(xdrs, &objp->xr_privs_len))
return (FALSE);
if (objp->xr_privs == NULL)
objp->xr_privs = malloc(objp->xr_privs_len);
if (!xdr_opaque(xdrs, (char *)objp->xr_privs,
objp->xr_privs_len))
return (FALSE);
if (!xdr_xpol_args(xdrs, &objp->xr_args))
return (FALSE);
if (!xdr_bool(xdrs, &more_data))
return (FALSE);
if (!more_data) {
objp->xr_next = NULL;
break;
}
if (objp->xr_next == NULL) {
objp->xr_next = (xpol_rule_t *)
mem_alloc(sizeof (xpol_rule_t));
if (objp->xr_next == NULL)
return (FALSE);
bzero(objp->xr_next, sizeof (xpol_rule_t));
}
objp = objp->xr_next;
}
} else if (xdrs->x_op == XDR_ENCODE) {
while (more_data) {
slen = d->pd_setsize;
if (!xdr_u_int(xdrs, &slen))
return (FALSE);
if (!xdr_opaque(xdrs, (char *)objp->xr_privs, slen))
return (FALSE);
if (!xdr_xpol_args(xdrs, &objp->xr_args))
return (FALSE);
objp = objp->xr_next;
if (objp == NULL)
more_data = FALSE;
if (!xdr_bool(xdrs, &more_data))
return (FALSE);
}
} else {
while (more_data) {
if (!xdr_u_int(xdrs, &objp->xr_privs_len))
return (FALSE);
if (!xdr_opaque(xdrs, (char *)objp->xr_privs,
objp->xr_privs_len))
return (FALSE);
free(objp->xr_privs); /* Works for DECODED stuff */
if (!xdr_xpol_args(xdrs, &objp->xr_args))
return (FALSE);
tmp_xpol_rule = objp;
objp = objp->xr_next;
if (objp == NULL)
more_data = FALSE;
if (!first_objp)
mem_free(tmp_xpol_rule, sizeof (xpol_rule_t));
else
first_objp = FALSE;
}
}
return (TRUE);
}