*/
#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "dlinklist.h"
/* we over allocate the data buffer to prevent too many realloc calls */
-#define REQ_OVER_ALLOCATION 256
+#define REQ_OVER_ALLOCATION 0
/* assume that a character will not consume more than 3 bytes per char */
#define MAX_BYTES_PER_CHAR 3
DLIST_REMOVE(req->transport->pending_recv, req);
}
- /* ahh, its so nice to destroy a complex structure in such a
- simple way! */
+ if (req->state == SMBCLI_REQUEST_ERROR &&
+ NT_STATUS_IS_OK(req->status)) {
+ req->status = NT_STATUS_INTERNAL_ERROR;
+ }
+
status = req->status;
talloc_free(req);
return status;
{
struct smbcli_request *req;
- req = talloc_named(NULL, sizeof(struct smbcli_request), "smcli_request");
+ req = talloc_p(transport, struct smbcli_request);
if (!req) {
return NULL;
}
setup a SMB packet at transport level
*/
struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
- uint8_t command, uint_t wct, uint_t buflen)
+ uint8_t command, uint_t wct, uint_t buflen)
{
struct smbcli_request *req;
SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
SSVAL(req->out.hdr,HDR_FLG2, 0);
- /* assign a mid */
- req->mid = smbcli_transport_next_mid(transport);
+ if (command != SMBtranss && command != SMBtranss2) {
+ /* assign a mid */
+ req->mid = smbcli_transport_next_mid(transport);
+ }
/* copy the pid, uid and mid to the request */
SSVAL(req->out.hdr, HDR_PID, 0);
way. This interface is used before a session is setup.
*/
struct smbcli_request *smbcli_request_setup_session(struct smbcli_session *session,
- uint8_t command, uint_t wct, uint_t buflen)
+ uint8_t command, uint_t wct, uint_t buflen)
{
struct smbcli_request *req;
- uint16_t flags2;
- uint32_t capabilities;
req = smbcli_request_setup_transport(session->transport, command, wct, buflen);
if (!req) return NULL;
req->session = session;
-
- flags2 = FLAGS2_LONG_PATH_COMPONENTS;
- capabilities = session->transport->negotiate.capabilities;
-
- if (capabilities & CAP_UNICODE) {
- flags2 |= FLAGS2_UNICODE_STRINGS;
- }
- if (capabilities & CAP_STATUS32) {
- flags2 |= FLAGS2_32_BIT_ERROR_CODES;
- }
- if (capabilities & CAP_EXTENDED_SECURITY) {
- flags2 |= FLAGS2_EXTENDED_SECURITY;
- }
- if (session->transport->negotiate.sign_info.doing_signing) {
- flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
- }
- SSVAL(req->out.hdr, HDR_FLG2, flags2);
+ SSVAL(req->out.hdr, HDR_FLG2, session->flags2);
SSVAL(req->out.hdr, HDR_PID, session->pid & 0xFFFF);
SSVAL(req->out.hdr, HDR_PIDHIGH, session->pid >> 16);
SSVAL(req->out.hdr, HDR_UID, session->vuid);
static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_size)
{
int delta;
- char *buf2;
+ uint8_t *buf2;
delta = new_size - req->out.data_size;
if (delta + req->out.size <= req->out.allocated) {
/* we need to realloc */
req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION;
- buf2 = talloc_realloc(req->out.buffer, req->out.allocated);
+ buf2 = talloc_realloc(req, req->out.buffer, req->out.allocated);
if (buf2 == NULL) {
smb_panic("out of memory in req_grow_allocation");
}
To cope with this req->out.ptr is supplied. This will be updated to
point at the same offset into the packet as before this call
*/
-void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size)
+static void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size)
{
int delta;
handle oplock break requests from the server - return True if the request was
an oplock break
*/
-BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const char *hdr, const char *vwv)
+BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const uint8_t *hdr, const uint8_t *vwv)
{
/* we must be very fussy about what we consider an oplock break to avoid
matching readbraw replies */
of bytes consumed in the packet is returned
*/
static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
- char **dest, const char *src, int byte_len, uint_t flags)
+ char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2, alignment=0;
ssize_t ret;
src_len = byte_len;
}
- src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2;
- if (src_len2 < src_len - 2) {
- /* include the termination if we didn't reach the end of the packet */
- src_len2 += 2;
- }
+ src_len2 = utf16_len_n(src, src_len);
/* ucs2 strings must be at least 2 bytes long */
if (src_len2 < 2) {
of bytes consumed in the packet is returned
*/
size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
- char **dest, const char *src, int byte_len, uint_t flags)
+ char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2;
ssize_t ret;
if (byte_len != -1 && src_len > byte_len) {
src_len = byte_len;
}
- src_len2 = strnlen(src, src_len);
+ src_len2 = strnlen((const char *)src, src_len);
if (src_len2 < src_len - 1) {
/* include the termination if we didn't reach the end of the packet */
src_len2++;
of bytes consumed in the packet is returned
*/
size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
- char **dest, const char *src, int byte_len, uint_t flags)
+ char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
if (!(flags & STR_ASCII) &&
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
if byte_len is -1 then limit the blob only by packet size
*/
-DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len)
+DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
{
int src_len;
/* check that a lump of data in a request is within the bounds of the data section of
the packet */
-static BOOL smbcli_req_data_oob(struct smbcli_request *req, const char *ptr, uint32_t count)
+static BOOL smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count)
{
/* be careful with wraparound! */
if (ptr < req->in.data ||
return False if any part is outside the data portion of the packet
*/
-BOOL smbcli_raw_pull_data(struct smbcli_request *req, const char *src, int len, char *dest)
+BOOL smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest)
{
if (len == 0) return True;
*/
static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx,
DATA_BLOB *blob, const char **dest,
- const char *src, int byte_len, uint_t flags)
+ const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2, alignment=0;
ssize_t ret;
char *dest2;
- if (src < (const char *)blob->data ||
- src >= (const char *)(blob->data + blob->length)) {
+ if (src < blob->data ||
+ src >= (blob->data + blob->length)) {
*dest = NULL;
return 0;
}
return 0;
}
- src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2;
-
- if (src_len2 < src_len - 2) {
- /* include the termination if we didn't reach the end of the packet */
- src_len2 += 2;
- }
+ src_len2 = utf16_len_n(src, src_len);
ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
if (ret == -1) {
*/
static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx,
DATA_BLOB *blob, const char **dest,
- const char *src, int byte_len, uint_t flags)
+ const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2;
ssize_t ret;
if (byte_len != -1 && src_len > byte_len) {
src_len = byte_len;
}
- src_len2 = strnlen(src, src_len);
+ src_len2 = strnlen((const char *)src, src_len);
if (src_len2 < src_len - 1) {
/* include the termination if we didn't reach the end of the packet */
max_len = (strlen(str)+2) * MAX_BYTES_PER_CHAR;
- blob->data = talloc_realloc(blob->data, blob->length + max_len);
+ blob->data = talloc_realloc(mem_ctx, blob->data, blob->length + max_len);
if (!blob->data) {
return 0;
}