ndr_client.c revision b1352070d318187b41b088da3533692976f3f225
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <string.h>
#include <strings.h>
#include <smbsrv/libmlrpc.h>
#define NDR_DEFAULT_FRAGSZ 8192
static void ndr_clnt_remove_hdr(ndr_stream_t *, int *);
int
{
int rc;
return (NDR_DRC_FAULT_API_SERVICE_INVALID);
return (NDR_DRC_FAULT_API_BIND_NO_SLOTS);
bhdr->assoc_group_id = 0;
/* Assign presentation context id */
/* Set up UUIDs and versions from the service */
if (rc != 0)
return (NDR_DRC_FAULT_API_SERVICE_INVALID);
if (rc != 0)
return (NDR_DRC_FAULT_API_SERVICE_INVALID);
/* Format and exchange the PDU */
return (NDR_DRC_FAULT_OUT_OF_MEMORY);
if (NDR_DRC_IS_FAULT(rc))
goto fault_exit;
goto fault_exit;
}
if (NDR_DRC_IS_FAULT(rc))
goto fault_exit;
/* done with buffers */
return (NDR_DRC_FAULT_RECEIVED_MALFORMED);
return (NDR_DRC_FAULT_RECEIVED_MALFORMED);
return (NDR_DRC_FAULT_RECEIVED_MALFORMED);
mbind->instance_specific = 0;
*ret_binding_p = mbind;
return (NDR_DRC_OK);
return (rc);
}
int
{
unsigned long recv_pdu_scan_offset;
int rc;
return (NDR_DRC_FAULT_API_SERVICE_INVALID);
if (NDR_DRC_IS_FAULT(rc))
return (rc);
/* Reserve room for hdr */
if (!NDR_DRC_IS_OK(rc))
goto fault_exit;
/*
* Now we have the PDU size, we need to set up the
* frag_length and calculate the alloc_hint.
*/
sizeof (ndr_request_hdr_t);
if (NDR_DRC_IS_FAULT(rc))
goto fault_exit;
if (NDR_DRC_IS_FAULT(rc))
goto fault_exit;
if (NDR_DRC_IS_FAULT(rc))
goto fault_exit;
goto fault_exit;
}
/*
* This is a multi-fragment response.
* Preserve the current scan offset while getting
* fragments so that we can continue afterward
* as if we had received the entire response as
* a single PDU.
*/
goto fault_exit;
}
}
if (NDR_DRC_IS_FAULT(rc))
goto fault_exit;
return (NDR_DRC_OK);
return (rc);
}
void
{
}
static void
{
hdr->rpc_vers_minor = 0;
#ifndef _BIG_ENDIAN
#endif
/* hdr->frag_length */
hdr->auth_length = 0;
}
/*
* ndr_clnt_remove_hdr
*
* Remove an RPC fragment header from the received data stream.
*
* Original RPC receive buffer:
* |- frag1 -| |-frag M(partial)-|
* +==================+=============+----+=================+
* | SmbTransact Rsp1 | SmbTransact | | SmbReadX RspN |
* | (with RPC hdr) | Rsp2 | .. | (with RPC hdr) |
* +-----+------------+-------------+ +-----+-----------+
* | hdr | data | data | .. | hdr | data |
* +=====+============+=============+----+=====+===========+
* <------
* ^ ^ ^
* | | |
* base_offset hdr data
*
* |-------------------------------------|-----------------|
* offset len
*
* RPC receive buffer (after this call):
* +==================+=============+----+===========+
* | SmbTransact Rsp1 | SmbTransact | | SmbReadX |
* | (with RPC hdr) | Rsp2 | .. | RspN |
* +-----+------------+-------------+ +-----------+
* | hdr | data | data | .. | data |
* +=====+============+=============+----+===========+
*/
static void
{
char *hdr;
char *data;
*nbytes -= NDR_RSP_HDR_SIZE;
}
/*
* ndr_clnt_get_frags
*
* A DCE RPC message that is larger than a single fragment is transmitted
* as a series of fragments: 5280 bytes for Windows NT and 4280 bytes for
* both Windows 2000 and 2003.
*
* Collect RPC fragments and append them to the receive stream buffer.
* Each received fragment has a header, which we need to remove as we
* build the full RPC PDU.
*
* The xa_read() calls will translate to SmbReadX requests. Note that
* there is no correspondence between SmbReadX buffering and DCE RPC
* fragment alignment.
*
* Return -1 on error. Otherwise, return the total data count of the
* complete RPC response upon success.
*/
static int
{
int frag_rcvd;
int frag_size;
int last_frag;
int nbytes;
/*
* The scan offest will be used to locate the frag header.
*/
do {
frag_rcvd = 0;
do {
return (-1);
if (frag_rcvd == 0) {
}
} while (!last_frag);
return (0);
}