#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>
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);
}
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);
}
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);
}
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);
}