smb_door_encdec.c revision 148c5f43199ca0b43fc8e3b643aab11cd66ea327
/*
* 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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdlib.h>
#include <strings.h>
#include <rpc/xdr.h>
#include <errno.h>
#include <syslog.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/smb_xdr.h>
#include <smbsrv/smb_door.h>
/*
* Generic XDR encoder.
*
* Returns a malloc'd, encoded buffer upon success.
* Otherwise, returns NULL.
*/
char *
smb_common_encode(void *data, xdrproc_t proc, size_t *rsize)
{
XDR xdrs;
char *buf;
size_t len;
if (proc == NULL || data == NULL || rsize == NULL) {
syslog(LOG_ERR, "smb_common_encode: invalid parameter");
return (NULL);
}
len = xdr_sizeof(proc, data);
if ((buf = malloc(len)) == NULL) {
syslog(LOG_ERR, "smb_common_encode: %m");
*rsize = 0;
return (NULL);
}
xdrmem_create(&xdrs, buf, len, XDR_ENCODE);
*rsize = len;
if (!proc(&xdrs, data)) {
syslog(LOG_DEBUG, "smb_common_encode: encode error");
free(buf);
buf = NULL;
*rsize = 0;
}
xdr_destroy(&xdrs);
return (buf);
}
/*
* Generic XDR decoder. Ensure that data is non-null and bzero'd.
*/
int
smb_common_decode(char *buf, size_t len, xdrproc_t proc, void *data)
{
XDR xdrs;
int rc = 0;
if (data == NULL)
return (-1);
xdrmem_create(&xdrs, buf, len, XDR_DECODE);
if (!proc(&xdrs, data))
rc = -1;
xdr_destroy(&xdrs);
return (rc);
}
char *
smb_string_encode(char *s, size_t *rsize)
{
smb_string_t obj;
XDR xdrs;
char *buf = NULL;
size_t len;
if ((obj.buf = s) == NULL) {
syslog(LOG_DEBUG, "smb_string_encode: invalid param");
goto smb_string_encode_failed;
}
len = xdr_sizeof(smb_string_xdr, &obj);
if ((buf = calloc(len, 1)) == NULL) {
syslog(LOG_DEBUG, "smb_string_encode: %m");
goto smb_string_encode_failed;
}
xdrmem_create(&xdrs, buf, len, XDR_ENCODE);
if (!smb_string_xdr(&xdrs, &obj)) {
syslog(LOG_DEBUG, "smb_string_encode: encode failed");
xdr_destroy(&xdrs);
free(buf);
goto smb_string_encode_failed;
}
xdr_destroy(&xdrs);
if (rsize)
*rsize = len;
return (buf);
smb_string_encode_failed:
if (rsize)
*rsize = 0;
return (NULL);
}
int
smb_string_decode(smb_string_t *obj, char *buf, size_t buflen)
{
XDR xdrs;
int rc = 0;
xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
bzero(obj, sizeof (smb_string_t));
if (!smb_string_xdr(&xdrs, obj))
rc = -1;
xdr_destroy(&xdrs);
return (rc);
}
/*
* Encode an lsa_account_t into a buffer.
*/
int
lsa_account_encode(lsa_account_t *acct, uint8_t *buf, uint32_t buflen)
{
XDR xdrs;
int rc = 0;
xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_ENCODE);
if (!lsa_account_xdr(&xdrs, acct))
rc = -1;
xdr_destroy(&xdrs);
return (rc);
}
/*
* Decode an XDR buffer into an lsa_account_t.
*/
int
lsa_account_decode(lsa_account_t *acct, uint8_t *buf, uint32_t buflen)
{
XDR xdrs;
int rc = 0;
xdrmem_create(&xdrs, (const caddr_t)buf, buflen, XDR_DECODE);
bzero(acct, sizeof (lsa_account_t));
if (!lsa_account_xdr(&xdrs, acct))
rc = -1;
xdr_destroy(&xdrs);
return (rc);
}
bool_t
lsa_account_xdr(XDR *xdrs, lsa_account_t *objp)
{
if (!xdr_uint16_t(xdrs, &objp->a_sidtype))
return (FALSE);
if (!xdr_uint32_t(xdrs, &objp->a_status))
return (FALSE);
if (!xdr_vector(xdrs, (char *)objp->a_domain, MAXNAMELEN,
sizeof (char), (xdrproc_t)xdr_char))
return (FALSE);
if (!xdr_vector(xdrs, (char *)objp->a_name, MAXNAMELEN,
sizeof (char), (xdrproc_t)xdr_char))
return (FALSE);
if (!xdr_vector(xdrs, (char *)objp->a_sid, SMB_SID_STRSZ,
sizeof (char), (xdrproc_t)xdr_char))
return (FALSE);
return (TRUE);
}