summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/cldap/cldap.c11
-rw-r--r--source4/libcli/cliconnect.c5
-rw-r--r--source4/libcli/composite/composite.c6
-rw-r--r--source4/libcli/dgram/dgramsocket.c6
-rw-r--r--source4/libcli/ldap/ldap_bind.c5
-rw-r--r--source4/libcli/ldap/ldap_client.c12
-rw-r--r--source4/libcli/ldap/ldap_ndr.h2
-rw-r--r--source4/libcli/nbt/libnbt.h2
-rw-r--r--source4/libcli/nbt/nbtsocket.c6
-rw-r--r--source4/libcli/raw/clisocket.c22
-rw-r--r--source4/libcli/raw/interfaces.h43
-rw-r--r--source4/libcli/raw/rawrequest.c6
-rw-r--r--source4/libcli/raw/rawtrans.c6
-rw-r--r--source4/libcli/resolve/host.c1
-rw-r--r--source4/libcli/resolve/nbtlist.c3
-rw-r--r--source4/libcli/resolve/resolve.c13
-rw-r--r--source4/libcli/smb2/break.c74
-rw-r--r--source4/libcli/smb2/config.mk2
-rw-r--r--source4/libcli/smb2/connect.c7
-rw-r--r--source4/libcli/smb2/create.c94
-rw-r--r--source4/libcli/smb2/read.c13
-rw-r--r--source4/libcli/smb2/request.c8
-rw-r--r--source4/libcli/smb2/smb2.h11
-rw-r--r--source4/libcli/smb2/transport.c43
-rw-r--r--source4/libcli/smb_composite/connect.c8
-rw-r--r--source4/libcli/smb_composite/fetchfile.c2
-rw-r--r--source4/libcli/smb_composite/fsinfo.c2
-rw-r--r--source4/libcli/wbclient/config.mk3
-rw-r--r--source4/libcli/wrepl/winsrepl.c6
29 files changed, 302 insertions, 120 deletions
diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c
index d10eeb8ffd..614bd51d2a 100644
--- a/source4/libcli/cldap/cldap.c
+++ b/source4/libcli/cldap/cldap.c
@@ -250,11 +250,7 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx,
cldap = talloc(mem_ctx, struct cldap_socket);
if (cldap == NULL) goto failed;
- if (event_ctx == NULL) {
- cldap->event_ctx = event_context_init(cldap);
- } else {
- cldap->event_ctx = talloc_reference(cldap, event_ctx);
- }
+ cldap->event_ctx = talloc_reference(cldap, event_ctx);
if (cldap->event_ctx == NULL) goto failed;
cldap->idr = idr_init(cldap);
@@ -601,8 +597,11 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
NTSTATUS status;
enum ndr_err_code ndr_err;
struct cldap_search search;
+ struct cldap_socket *cldap;
DATA_BLOB *data;
+ cldap = req->cldap;
+
status = cldap_search_recv(req, mem_ctx, &search);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -620,7 +619,7 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
data = search.out.response->attributes[0].values;
ndr_err = ndr_pull_union_blob_all(data, mem_ctx,
- req->cldap->iconv_convenience,
+ cldap->iconv_convenience,
&io->out.netlogon,
io->in.version & 0xF,
(ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon);
diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c
index 4858a96110..c20a7fd935 100644
--- a/source4/libcli/cliconnect.c
+++ b/source4/libcli/cliconnect.c
@@ -33,13 +33,14 @@
*/
bool smbcli_socket_connect(struct smbcli_state *cli, const char *server,
const char **ports,
+ struct event_context *ev_ctx,
struct resolve_context *resolve_ctx,
struct smbcli_options *options)
{
struct smbcli_socket *sock;
- sock = smbcli_sock_connect_byname(server, ports, NULL, resolve_ctx,
- NULL);
+ sock = smbcli_sock_connect_byname(server, ports, NULL,
+ resolve_ctx, ev_ctx);
if (sock == NULL) return false;
diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c
index 26169e7838..966f56cba8 100644
--- a/source4/libcli/composite/composite.c
+++ b/source4/libcli/composite/composite.c
@@ -42,7 +42,11 @@ _PUBLIC_ struct composite_context *composite_create(TALLOC_CTX *mem_ctx,
c = talloc_zero(mem_ctx, struct composite_context);
if (!c) return NULL;
c->state = COMPOSITE_STATE_IN_PROGRESS;
- c->event_ctx = ev;
+ c->event_ctx = talloc_reference(c, ev);
+ if (!c->event_ctx) {
+ talloc_free(c);
+ return NULL;
+ }
return c;
}
diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c
index 130d8ae870..06b7bd5771 100644
--- a/source4/libcli/dgram/dgramsocket.c
+++ b/source4/libcli/dgram/dgramsocket.c
@@ -167,11 +167,7 @@ struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx,
dgmsock = talloc(mem_ctx, struct nbt_dgram_socket);
if (dgmsock == NULL) goto failed;
- if (event_ctx == NULL) {
- dgmsock->event_ctx = event_context_init(dgmsock);
- } else {
- dgmsock->event_ctx = talloc_reference(dgmsock, event_ctx);
- }
+ dgmsock->event_ctx = talloc_reference(dgmsock, event_ctx);
if (dgmsock->event_ctx == NULL) goto failed;
status = socket_create("ip", SOCKET_TYPE_DGRAM, &dgmsock->sock, 0);
diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c
index 2c04edf950..e1569e7296 100644
--- a/source4/libcli/ldap/ldap_bind.c
+++ b/source4/libcli/ldap/ldap_bind.c
@@ -200,7 +200,7 @@ static struct ldap_message *new_ldap_sasl_bind_msg(struct ldap_connection *conn,
/*
perform a sasl bind using the given credentials
*/
-_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
+_PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
struct cli_credentials *creds,
struct loadparm_context *lp_ctx)
{
@@ -223,7 +223,8 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
gensec_init(lp_ctx);
- status = gensec_client_start(conn, &conn->gensec, NULL, lp_ctx);
+ status = gensec_client_start(conn, &conn->gensec,
+ conn->event.event_ctx, lp_ctx);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status)));
goto failed;
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 296a7b11f2..bca867b033 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -48,17 +48,13 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx,
{
struct ldap_connection *conn;
- conn = talloc_zero(mem_ctx, struct ldap_connection);
- if (conn == NULL) {
+ if (ev == NULL) {
return NULL;
}
- if (ev == NULL) {
- ev = event_context_init(conn);
- if (ev == NULL) {
- talloc_free(conn);
- return NULL;
- }
+ conn = talloc_zero(mem_ctx, struct ldap_connection);
+ if (conn == NULL) {
+ return NULL;
}
conn->next_messageid = 1;
diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h
index dfbb723c36..ee1f702c78 100644
--- a/source4/libcli/ldap/ldap_ndr.h
+++ b/source4/libcli/ldap/ldap_ndr.h
@@ -1,6 +1,8 @@
#ifndef __LIBCLI_LDAP_LDAP_NDR_H__
#define __LIBCLI_LDAP_LDAP_NDR_H__
+#include "librpc/gen_ndr/ndr_misc.h"
+
char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value);
char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid);
char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid);
diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h
index 14cec3a024..0b01365510 100644
--- a/source4/libcli/nbt/libnbt.h
+++ b/source4/libcli/nbt/libnbt.h
@@ -330,7 +330,7 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *)
-NDR_SCALAR_PROTO(nbt_string, const char *);
+NDR_SCALAR_PROTO(nbt_string, const char *)
NDR_BUFFER_PROTO(nbt_name, struct nbt_name)
NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode);
diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c
index 747127980a..5d4611e2d9 100644
--- a/source4/libcli/nbt/nbtsocket.c
+++ b/source4/libcli/nbt/nbtsocket.c
@@ -318,11 +318,7 @@ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
nbtsock = talloc(mem_ctx, struct nbt_name_socket);
if (nbtsock == NULL) goto failed;
- if (event_ctx == NULL) {
- nbtsock->event_ctx = event_context_init(nbtsock);
- } else {
- nbtsock->event_ctx = talloc_reference(nbtsock, event_ctx);
- }
+ nbtsock->event_ctx = talloc_reference(nbtsock, event_ctx);
if (nbtsock->event_ctx == NULL) goto failed;
status = socket_create("ip", SOCKET_TYPE_DGRAM, &nbtsock->sock, 0);
diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c
index 1dcf2d1c53..49838e8a1c 100644
--- a/source4/libcli/raw/clisocket.c
+++ b/source4/libcli/raw/clisocket.c
@@ -59,12 +59,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx,
if (result == NULL) goto failed;
result->state = COMPOSITE_STATE_IN_PROGRESS;
- if (event_ctx != NULL) {
- result->event_ctx = talloc_reference(result, event_ctx);
- } else {
- result->event_ctx = event_context_init(result);
- }
-
+ result->event_ctx = talloc_reference(result, event_ctx);
if (result->event_ctx == NULL) goto failed;
state = talloc(result, struct sock_connect_state);
@@ -202,6 +197,11 @@ _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, cons
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
struct smbcli_socket *result;
+ if (event_ctx == NULL) {
+ DEBUG(0, ("Invalid NULL event context passed in as parameter\n"));
+ return NULL;
+ }
+
if (tmp_ctx == NULL) {
DEBUG(0, ("talloc_new failed\n"));
return NULL;
@@ -214,16 +214,6 @@ _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, cons
return NULL;
}
- if (event_ctx == NULL) {
- event_ctx = event_context_init(mem_ctx);
- }
-
- if (event_ctx == NULL) {
- DEBUG(0, ("event_context_init failed\n"));
- talloc_free(tmp_ctx);
- return NULL;
- }
-
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ((p = strchr(name, '#'))) {
name_type = strtol(p+1, NULL, 16);
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 3965c58204..bad3743721 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -1587,6 +1587,14 @@ union smb_open {
/* optional list of extended attributes */
struct smb_ea_list eas;
+
+ struct smb2_create_blobs {
+ uint32_t num_blobs;
+ struct smb2_create_blob {
+ const char *tag;
+ DATA_BLOB data;
+ } *blobs;
+ } blobs;
} in;
struct {
union smb_handle file;
@@ -1706,19 +1714,27 @@ union smb_read {
/* static body buffer 48 (0x30) bytes */
/* uint16_t buffer_code; 0x31 = 0x30 + 1 */
- uint16_t _pad;
+ uint8_t _pad;
+ uint8_t reserved;
uint32_t length;
uint64_t offset;
/* struct smb2_handle handle; */
- uint64_t unknown1; /* 0x0000000000000000 */
- uint64_t unknown2; /* 0x0000000000000000 */
+ uint32_t min_count;
+ uint32_t channel;
+ uint32_t remaining;
+ /* the docs give no indication of what
+ these channel variables are for */
+ uint16_t channel_offset;
+ uint16_t channel_length;
} in;
struct {
/* static body buffer 16 (0x10) bytes */
/* uint16_t buffer_code; 0x11 = 0x10 + 1 */
- /* uint16_t data_ofs; */
+ /* uint8_t data_ofs; */
+ /* uint8_t reserved; */
/* uint32_t data_size; */
- uint64_t unknown1; /* 0x0000000000000000 */
+ uint32_t remaining;
+ uint32_t reserved;
/* dynamic body */
DATA_BLOB data;
@@ -1846,7 +1862,8 @@ enum smb_lock_level {
RAW_LOCK_LOCK,
RAW_LOCK_UNLOCK,
RAW_LOCK_LOCKX,
- RAW_LOCK_SMB2
+ RAW_LOCK_SMB2,
+ RAW_LOCK_SMB2_BREAK
};
/* the generic interface is defined to be equal to the lockingX interface */
@@ -1909,6 +1926,20 @@ union smb_lock {
uint16_t unknown1;
} out;
} smb2;
+
+ /* SMB2 Break */
+ struct smb2_break {
+ enum smb_lock_level level;
+ struct {
+ union smb_handle file;
+
+ /* static body buffer 24 (0x18) bytes */
+ uint8_t oplock_level;
+ uint8_t reserved;
+ uint32_t reserved2;
+ /* struct smb2_handle handle; */
+ } in, out;
+ } smb2_break;
};
diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c
index a42c710547..ef856c6ea1 100644
--- a/source4/libcli/raw/rawrequest.c
+++ b/source4/libcli/raw/rawrequest.c
@@ -700,10 +700,10 @@ DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_
static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
{
/* be careful with wraparound! */
- if (ptr < bufinfo->data ||
- ptr >= bufinfo->data + bufinfo->data_size ||
+ if ((uintptr_t)ptr < (uintptr_t)bufinfo->data ||
+ (uintptr_t)ptr >= (uintptr_t)bufinfo->data + bufinfo->data_size ||
count > bufinfo->data_size ||
- ptr + count > bufinfo->data + bufinfo->data_size) {
+ (uintptr_t)ptr + count > (uintptr_t)bufinfo->data + bufinfo->data_size) {
return true;
}
return false;
diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c
index 29881afd2b..0f15b2151b 100644
--- a/source4/libcli/raw/rawtrans.c
+++ b/source4/libcli/raw/rawtrans.c
@@ -40,10 +40,10 @@ static bool raw_trans_oob(struct smbcli_request *req,
ptr = req->in.hdr + offset;
/* be careful with wraparound! */
- if (ptr < req->in.data ||
- ptr >= req->in.data + req->in.data_size ||
+ if ((uintptr_t)ptr < (uintptr_t)req->in.data ||
+ (uintptr_t)ptr >= (uintptr_t)req->in.data + req->in.data_size ||
count > req->in.data_size ||
- ptr + count > req->in.data + req->in.data_size) {
+ (uintptr_t)ptr + count > (uintptr_t)req->in.data + req->in.data_size) {
return true;
}
return false;
diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c
index 4b8f3f9553..1a695432ee 100644
--- a/source4/libcli/resolve/host.c
+++ b/source4/libcli/resolve/host.c
@@ -135,7 +135,6 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx,
c = composite_create(mem_ctx, event_ctx);
if (c == NULL) return NULL;
- c->event_ctx = talloc_reference(c, event_ctx);
if (composite_nomem(c->event_ctx, c)) return c;
state = talloc(c, struct host_state);
diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c
index 887bdd7ecf..8f085c5404 100644
--- a/source4/libcli/resolve/nbtlist.c
+++ b/source4/libcli/resolve/nbtlist.c
@@ -110,10 +110,9 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
struct nbtlist_state *state;
int i;
- c = composite_create(event_ctx, event_ctx);
+ c = composite_create(mem_ctx, event_ctx);
if (c == NULL) return NULL;
- c->event_ctx = talloc_reference(c, event_ctx);
if (composite_nomem(c->event_ctx, c)) return c;
state = talloc(c, struct nbtlist_state);
diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c
index 33ace09443..aaf9ff1f8d 100644
--- a/source4/libcli/resolve/resolve.c
+++ b/source4/libcli/resolve/resolve.c
@@ -136,19 +136,14 @@ struct composite_context *resolve_name_send(struct resolve_context *ctx,
struct composite_context *c;
struct resolve_state *state;
- c = composite_create(event_ctx, event_ctx);
- if (c == NULL) return NULL;
-
- if (ctx == NULL) {
+ if (ctx == NULL || event_ctx == NULL) {
composite_error(c, NT_STATUS_INVALID_PARAMETER);
return c;
}
- if (event_ctx == NULL) {
- c->event_ctx = event_context_init(c);
- } else {
- c->event_ctx = talloc_reference(c, event_ctx);
- }
+ c = composite_create(ctx, event_ctx);
+ if (c == NULL) return NULL;
+
if (composite_nomem(c->event_ctx, c)) return c;
state = talloc(c, struct resolve_state);
diff --git a/source4/libcli/smb2/break.c b/source4/libcli/smb2/break.c
new file mode 100644
index 0000000000..fe0cceb829
--- /dev/null
+++ b/source4/libcli/smb2/break.c
@@ -0,0 +1,74 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ SMB2 client oplock break handling
+
+ Copyright (C) Stefan Metzmacher 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+
+/*
+ send a break request
+*/
+struct smb2_request *smb2_break_send(struct smb2_tree *tree, struct smb2_break *io)
+{
+ struct smb2_request *req;
+
+ req = smb2_request_init_tree(tree, SMB2_OP_BREAK, 0x18, false, 0);
+ if (req == NULL) return NULL;
+
+ SCVAL(req->out.body, 0x02, io->in.oplock_level);
+ SCVAL(req->out.body, 0x03, io->in.reserved);
+ SIVAL(req->out.body, 0x04, io->in.reserved2);
+ smb2_push_handle(req->out.body+0x08, &io->in.file.handle);
+
+ smb2_transport_send(req);
+
+ return req;
+}
+
+
+/*
+ recv a break reply
+*/
+NTSTATUS smb2_break_recv(struct smb2_request *req, struct smb2_break *io)
+{
+ if (!smb2_request_receive(req) ||
+ !smb2_request_is_ok(req)) {
+ return smb2_request_destroy(req);
+ }
+
+ SMB2_CHECK_PACKET_RECV(req, 0x18, false);
+
+ io->out.oplock_level = CVAL(req->in.body, 0x02);
+ io->out.reserved = CVAL(req->in.body, 0x03);
+ io->out.reserved2 = IVAL(req->in.body, 0x04);
+ smb2_pull_handle(req->in.body+0x08, &io->out.file.handle);
+
+ return smb2_request_destroy(req);
+}
+
+/*
+ sync flush request
+*/
+NTSTATUS smb2_break(struct smb2_tree *tree, struct smb2_break *io)
+{
+ struct smb2_request *req = smb2_break_send(tree, io);
+ return smb2_break_recv(req, io);
+}
diff --git a/source4/libcli/smb2/config.mk b/source4/libcli/smb2/config.mk
index e95997db54..18f6245a3e 100644
--- a/source4/libcli/smb2/config.mk
+++ b/source4/libcli/smb2/config.mk
@@ -6,5 +6,5 @@ LIBCLI_SMB2_OBJ_FILES = $(addprefix libcli/smb2/, \
transport.o request.o negprot.o session.o tcon.o \
create.o close.o connect.o getinfo.o write.o read.o \
setinfo.o find.o ioctl.o logoff.o tdis.o flush.o \
- lock.o notify.o cancel.o keepalive.o)
+ lock.o notify.o cancel.o keepalive.o break.o)
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index d68b85ad54..59d4e6ea2d 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -121,7 +121,7 @@ static void continue_socket(struct composite_context *creq)
struct smbcli_socket *sock;
struct smb2_transport *transport;
struct smb2_request *req;
- uint16_t dialects[1];
+ uint16_t dialects[2];
c->status = smbcli_sock_connect_recv(creq, state, &sock);
if (!composite_is_ok(c)) return;
@@ -130,11 +130,12 @@ static void continue_socket(struct composite_context *creq)
if (composite_nomem(transport, c)) return;
ZERO_STRUCT(state->negprot);
- state->negprot.in.dialect_count = 1;
+ state->negprot.in.dialect_count = 2;
state->negprot.in.security_mode = 0;
state->negprot.in.capabilities = 0;
unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
- dialects[0] = SMB2_DIALECT_REVISION;
+ dialects[0] = 0;
+ dialects[1] = SMB2_DIALECT_REVISION;
state->negprot.in.dialects = dialects;
req = smb2_negprot_send(transport, &state->negprot);
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 999c10ab08..6ac32a494f 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -28,30 +28,59 @@
/*
add a blob to a smb2_create attribute blob
*/
-NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
- const char *tag,
- DATA_BLOB add, bool last)
+static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
+ const struct smb2_create_blob *blob,
+ bool last)
{
- uint32_t ofs = blob->length;
- size_t tag_length = strlen(tag);
- uint8_t pad = smb2_padding_size(add.length+tag_length, 8);
- if (!data_blob_realloc(mem_ctx, blob,
- blob->length + 0x14 + tag_length + add.length + pad))
+ uint32_t ofs = buffer->length;
+ size_t tag_length = strlen(blob->tag);
+ uint8_t pad = smb2_padding_size(blob->data.length+tag_length, 4);
+
+ if (!data_blob_realloc(mem_ctx, buffer,
+ buffer->length + 0x14 + tag_length + blob->data.length + pad))
return NT_STATUS_NO_MEMORY;
-
+
if (last) {
- SIVAL(blob->data, ofs+0x00, 0);
+ SIVAL(buffer->data, ofs+0x00, 0);
} else {
- SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad);
+ SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad);
}
- SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */
- SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */
- SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
- SIVAL(blob->data, ofs+0x0C, add.length);
- memcpy(blob->data+ofs+0x10, tag, tag_length);
- SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */
- memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length);
- memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad);
+ SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */
+ SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */
+ SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
+ SIVAL(buffer->data, ofs+0x0C, blob->data.length);
+ memcpy(buffer->data+ofs+0x10, blob->tag, tag_length);
+ SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */
+ memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length);
+ memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad);
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b,
+ const char *tag, DATA_BLOB data)
+{
+ struct smb2_create_blob *array;
+
+ array = talloc_realloc(mem_ctx, b->blobs,
+ struct smb2_create_blob,
+ b->num_blobs + 1);
+ NT_STATUS_HAVE_NO_MEMORY(array);
+ b->blobs = array;
+
+ b->blobs[b->num_blobs].tag = talloc_strdup(b->blobs, tag);
+ NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].tag);
+
+ if (data.data) {
+ b->blobs[b->num_blobs].data = data_blob_talloc(b->blobs,
+ data.data,
+ data.length);
+ NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].data.data);
+ } else {
+ b->blobs[b->num_blobs].data = data_blob(NULL, 0);
+ }
+
+ b->num_blobs += 1;
return NT_STATUS_OK;
}
@@ -64,6 +93,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
struct smb2_request *req;
NTSTATUS status;
DATA_BLOB blob = data_blob(NULL, 0);
+ uint32_t i;
req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0);
if (req == NULL) return NULL;
@@ -89,7 +119,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
DATA_BLOB b = data_blob_talloc(req, NULL,
ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas));
ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas);
- status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false);
+ status = smb2_create_blob_add(req, &io->in.blobs,
+ SMB2_CREATE_TAG_EXTA, b);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
return NULL;
@@ -99,13 +130,30 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
/* an empty MxAc tag seems to be used to ask the server to
return the maximum access mask allowed on the file */
- status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC,
- data_blob(NULL, 0), true);
-
+ status = smb2_create_blob_add(req, &io->in.blobs,
+ SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0));
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
return NULL;
}
+
+ for (i=0; i < io->in.blobs.num_blobs; i++) {
+ bool last = false;
+ const struct smb2_create_blob *c;
+
+ if ((i + 1) == io->in.blobs.num_blobs) {
+ last = true;
+ }
+
+ c = &io->in.blobs.blobs[i];
+ status = smb2_create_blob_push_one(req, &blob,
+ c, last);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(req);
+ return NULL;
+ }
+ }
+
status = smb2_push_o32s32_blob(&req->out, 0x30, blob);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
diff --git a/source4/libcli/smb2/read.c b/source4/libcli/smb2/read.c
index b61f918481..9d40e32a4d 100644
--- a/source4/libcli/smb2/read.c
+++ b/source4/libcli/smb2/read.c
@@ -33,12 +33,16 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io
req = smb2_request_init_tree(tree, SMB2_OP_READ, 0x30, true, 0);
if (req == NULL) return NULL;
- SSVAL(req->out.body, 0x02, 0); /* pad */
+ SCVAL(req->out.body, 0x02, 0); /* pad */
+ SCVAL(req->out.body, 0x03, 0); /* reserved */
SIVAL(req->out.body, 0x04, io->in.length);
SBVAL(req->out.body, 0x08, io->in.offset);
smb2_push_handle(req->out.body+0x10, &io->in.file.handle);
- SBVAL(req->out.body, 0x20, io->in.unknown1);
- SBVAL(req->out.body, 0x28, io->in.unknown2);
+ SIVAL(req->out.body, 0x20, io->in.min_count);
+ SIVAL(req->out.body, 0x24, io->in.channel);
+ SIVAL(req->out.body, 0x28, io->in.remaining);
+ SSVAL(req->out.body, 0x2C, io->in.channel_offset);
+ SSVAL(req->out.body, 0x2E, io->in.channel_length);
smb2_transport_send(req);
@@ -67,7 +71,8 @@ NTSTATUS smb2_read_recv(struct smb2_request *req,
return status;
}
- io->out.unknown1 = BVAL(req->in.body, 0x08);
+ io->out.remaining = IVAL(req->in.body, 0x08);
+ io->out.reserved = IVAL(req->in.body, 0x0C);
return smb2_request_destroy(req);
}
diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c
index 2471fcaa4d..f52b0ceef2 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -211,10 +211,10 @@ bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size)
return false;
}
/* be careful with wraparound! */
- if (ptr < buf->body ||
- ptr >= buf->body + buf->body_size ||
+ if ((uintptr_t)ptr < (uintptr_t)buf->body ||
+ (uintptr_t)ptr >= (uintptr_t)buf->body + buf->body_size ||
size > buf->body_size ||
- ptr + size > buf->body + buf->body_size) {
+ (uintptr_t)ptr + size > (uintptr_t)buf->body + buf->body_size) {
return true;
}
return false;
@@ -669,7 +669,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf,
}
if (*str == 0) {
- blob.data = str;
+ blob.data = discard_const(str);
blob.length = 0;
return smb2_push_o16s16_blob(buf, ofs, blob);
}
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 726df64090..ae66a6e0d3 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -21,6 +21,8 @@
#include "libcli/raw/request.h"
+struct smb2_handle;
+
struct smb2_options {
uint32_t timeout;
};
@@ -58,6 +60,15 @@ struct smb2_transport {
void *private;
uint_t period;
} idle;
+
+ struct {
+ /* a oplock break request handler */
+ bool (*handler)(struct smb2_transport *transport,
+ const struct smb2_handle *handle,
+ uint8_t level, void *private_data);
+ /* private data passed to the oplock handler */
+ void *private_data;
+ } oplock;
};
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index af19fcb0a9..8eb60a06f1 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -140,6 +140,44 @@ void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status)
}
}
+static bool smb2_handle_oplock_break(struct smb2_transport *transport,
+ const DATA_BLOB *blob)
+{
+ uint8_t *hdr;
+ uint16_t opcode;
+ uint64_t seqnum;
+
+ hdr = blob->data+NBT_HDR_SIZE;
+
+ if (blob->length < (SMB2_MIN_SIZE+0x18)) {
+ DEBUG(1,("Discarding smb2 oplock reply of size %u\n",
+ blob->length));
+ return false;
+ }
+
+ opcode = SVAL(hdr, SMB2_HDR_OPCODE);
+ seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
+
+ if ((opcode != SMB2_OP_BREAK) ||
+ (seqnum != UINT64_MAX)) {
+ return false;
+ }
+
+ if (transport->oplock.handler) {
+ uint8_t *body = hdr+SMB2_HDR_BODY;
+ struct smb2_handle h;
+ uint8_t level;
+
+ level = CVAL(body, 0x02);
+ smb2_pull_handle(body+0x08, &h);
+
+ transport->oplock.handler(transport, &h, level,
+ transport->oplock.private_data);
+ }
+
+ return true;
+}
+
/*
we have a full request in our receive buffer - match it to a pending request
and process
@@ -167,6 +205,11 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
goto error;
}
+ if (smb2_handle_oplock_break(transport, &blob)) {
+ talloc_free(buffer);
+ return NT_STATUS_OK;
+ }
+
flags = IVAL(hdr, SMB2_HDR_FLAGS);
seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c
index c44c62f868..c4abfa5e37 100644
--- a/source4/libcli/smb_composite/connect.c
+++ b/source4/libcli/smb_composite/connect.c
@@ -451,17 +451,15 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec
c = talloc_zero(mem_ctx, struct composite_context);
if (c == NULL) goto failed;
+ c->event_ctx = talloc_reference(c, event_ctx);
+ if (c->event_ctx == NULL) goto failed;
+
state = talloc_zero(c, struct connect_state);
if (state == NULL) goto failed;
- if (event_ctx == NULL) {
- event_ctx = event_context_init(mem_ctx);
- }
-
state->io = io;
c->state = COMPOSITE_STATE_IN_PROGRESS;
- c->event_ctx = talloc_reference(c, event_ctx);
c->private_data = state;
state->stage = CONNECT_RESOLVE;
diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c
index d8d7481270..9cd02a51f4 100644
--- a/source4/libcli/smb_composite/fetchfile.c
+++ b/source4/libcli/smb_composite/fetchfile.c
@@ -62,7 +62,6 @@ static NTSTATUS fetchfile_connect(struct composite_context *c,
state->creq->async.fn = fetchfile_composite_handler;
state->stage = FETCHFILE_READ;
- c->event_ctx = talloc_reference(c, state->creq->event_ctx);
return NT_STATUS_OK;
}
@@ -158,7 +157,6 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc
c->state = COMPOSITE_STATE_IN_PROGRESS;
state->stage = FETCHFILE_CONNECT;
- c->event_ctx = talloc_reference(c, state->creq->event_ctx);
c->private_data = state;
return c;
diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c
index 2ec13df9b6..270d71f518 100644
--- a/source4/libcli/smb_composite/fsinfo.c
+++ b/source4/libcli/smb_composite/fsinfo.c
@@ -52,7 +52,6 @@ static NTSTATUS fsinfo_connect(struct composite_context *c,
state->req->async.fn = fsinfo_raw_handler;
state->stage = FSINFO_QUERY;
- c->event_ctx = talloc_reference(c, state->req->session->transport->socket->event.ctx);
return NT_STATUS_OK;
}
@@ -158,7 +157,6 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree,
c->state = COMPOSITE_STATE_IN_PROGRESS;
state->stage = FSINFO_CONNECT;
- c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx);
c->private_data = state;
state->creq = smb_composite_connect_send(state->connect, state,
diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk
index 9384a172ff..94e30d44f1 100644
--- a/source4/libcli/wbclient/config.mk
+++ b/source4/libcli/wbclient/config.mk
@@ -1,4 +1,5 @@
[SUBSYSTEM::LIBWBCLIENT]
-OBJ_FILES = wbclient.o
PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS
PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING
+
+LIBWBCLIENT_OBJ_FILES = libcli/wbclient/wbclient.o
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c
index 3e7793c0c7..0a4e52bd7b 100644
--- a/source4/libcli/wrepl/winsrepl.c
+++ b/source4/libcli/wrepl/winsrepl.c
@@ -172,11 +172,7 @@ struct wrepl_socket *wrepl_socket_init(TALLOC_CTX *mem_ctx,
wrepl_socket = talloc_zero(mem_ctx, struct wrepl_socket);
if (!wrepl_socket) return NULL;
- if (event_ctx == NULL) {
- wrepl_socket->event.ctx = event_context_init(wrepl_socket);
- } else {
- wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx);
- }
+ wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx);
if (!wrepl_socket->event.ctx) goto failed;
wrepl_socket->iconv_convenience = iconv_convenience;