*/
#include "includes.h"
+#include "events.h"
#include "dlinklist.h"
#include "smb_server/smb_server.h"
/* we over allocate the data buffer to prevent too many realloc calls */
-#define REQ_OVER_ALLOCATION 256
+#define REQ_OVER_ALLOCATION 0
/* destroy a request structure */
void req_destroy(struct smbsrv_request *req)
/* over allocate by a small amount */
req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;
- req->out.buffer = talloc_realloc(req, req->out.buffer, req->out.allocated);
+ req->out.buffer = talloc_realloc(req, req->out.buffer,
+ uint8_t, req->out.allocated);
if (!req->out.buffer) {
smbsrv_terminate_connection(req->smb_conn, "allocation failed");
+ return;
}
req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
*/
void req_setup_reply(struct smbsrv_request *req, uint_t wct, uint_t buflen)
{
+ uint16_t flags2;
+
if (req->chain_count != 0) {
req_setup_chain_reply(req, wct, buflen);
return;
/* over allocate by a small amount */
req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;
- req->out.buffer = talloc(req, req->out.allocated);
+ req->out.buffer = talloc_size(req, req->out.allocated);
if (!req->out.buffer) {
smbsrv_terminate_connection(req->smb_conn, "allocation failed");
+ return;
+ }
+
+ flags2 = FLAGS2_LONG_PATH_COMPONENTS |
+ FLAGS2_EXTENDED_ATTRIBUTES |
+ FLAGS2_IS_LONG_NAME;
+ flags2 |= (req->flags2 & (FLAGS2_UNICODE_STRINGS|FLAGS2_EXTENDED_SECURITY));
+ if (req->smb_conn->negotiate.client_caps & CAP_STATUS32) {
+ flags2 |= FLAGS2_32_BIT_ERROR_CODES;
}
req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
SCVAL(req->out.hdr, HDR_WCT, wct);
SSVAL(req->out.vwv, VWV(wct), buflen);
-
memcpy(req->out.hdr, "\377SMB", 4);
SCVAL(req->out.hdr,HDR_FLG, FLAG_REPLY | FLAG_CASELESS_PATHNAMES);
- SSVAL(req->out.hdr,HDR_FLG2,
- (req->flags2 & FLAGS2_UNICODE_STRINGS) |
- FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_32_BIT_ERROR_CODES | FLAGS2_EXTENDED_SECURITY);
-
+ SSVAL(req->out.hdr,HDR_FLG2, flags2);
SSVAL(req->out.hdr,HDR_PIDHIGH,0);
memset(req->out.hdr + HDR_SS_FIELD, 0, 10);
static void req_grow_allocation(struct smbsrv_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, req->out.buffer, req->out.allocated);
+ buf2 = talloc_realloc(req, req->out.buffer, uint8_t, req->out.allocated);
if (buf2 == NULL) {
smb_panic("out of memory in req_grow_allocation");
}
if dest_len is -1 then no limit applies
*/
-size_t req_push_str(struct smbsrv_request *req, char *dest, const char *str, int dest_len, uint_t flags)
+size_t req_push_str(struct smbsrv_request *req, uint8_t *dest, const char *str, int dest_len, uint_t flags)
{
size_t len;
uint_t grow_size;
- char *buf0;
+ uint8_t *buf0;
const int max_bytes_per_char = 3;
if (!(flags & (STR_ASCII|STR_UNICODE))) {
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
-static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const char *src, int byte_len, uint_t flags)
+static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2, alignment=0;
ssize_t ret;
}
src_len2 = utf16_len_n(src, src_len);
+ if (src_len2 == 0) {
+ *dest = talloc_strdup(req, "");
+ return src_len2 + alignment;
+ }
+
ret = convert_string_talloc(req, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
if (ret == -1) {
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
-static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const char *src, int byte_len, uint_t flags)
+static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2;
ssize_t ret;
}
}
- 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++;
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
-size_t req_pull_string(struct smbsrv_request *req, const char **dest, const char *src, int byte_len, uint_t flags)
+size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
if (!(flags & STR_ASCII) &&
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
on failure *dest is set to the zero length string. This seems to
match win2000 behaviour
*/
-size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const char *src, uint_t flags)
+size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint8_t *src, uint_t flags)
{
ssize_t ret;
return False if any part is outside the data portion of the packet
*/
-BOOL req_pull_blob(struct smbsrv_request *req, const char *src, int len, DATA_BLOB *blob)
+BOOL req_pull_blob(struct smbsrv_request *req, const uint8_t *src, int len, DATA_BLOB *blob)
{
if (len != 0 && req_data_oob(req, src, len)) {
return False;
/* check that a lump of data in a request is within the bounds of the data section of
the packet */
-BOOL req_data_oob(struct smbsrv_request *req, const char *ptr, uint32_t count)
+BOOL req_data_oob(struct smbsrv_request *req, const uint8_t *ptr, uint32_t count)
{
if (count == 0) {
return False;
/*
pull an open file handle from a packet, taking account of the chained_fnum
*/
-uint16_t req_fnum(struct smbsrv_request *req, const char *base, uint_t offset)
+uint16_t req_fnum(struct smbsrv_request *req, const uint8_t *base, uint_t offset)
{
if (req->chained_fnum != -1) {
return req->chained_fnum;