summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/auth/config.mk13
-rw-r--r--source4/libcli/cldap/cldap.c44
-rw-r--r--source4/libcli/cldap/cldap.h7
-rw-r--r--source4/libcli/cliconnect.c5
-rw-r--r--source4/libcli/clifile.c11
-rw-r--r--source4/libcli/composite/composite.c25
-rw-r--r--source4/libcli/composite/composite.h1
-rw-r--r--source4/libcli/config.mk200
-rw-r--r--source4/libcli/dgram/dgramsocket.c6
-rw-r--r--source4/libcli/dgram/libdgram.h34
-rw-r--r--source4/libcli/dgram/netlogon.c45
-rw-r--r--source4/libcli/dgram/ntlogon.c128
-rw-r--r--source4/libcli/ldap/config.mk19
-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/ndr_netlogon.c209
-rw-r--r--source4/libcli/netlogon.c239
-rw-r--r--source4/libcli/netlogon.h54
-rw-r--r--source4/libcli/raw/clisocket.c22
-rw-r--r--source4/libcli/raw/clitree.c5
-rw-r--r--source4/libcli/raw/interfaces.h87
-rw-r--r--source4/libcli/raw/raweas.c9
-rw-r--r--source4/libcli/raw/rawfile.c4
-rw-r--r--source4/libcli/raw/rawfileinfo.c3
-rw-r--r--source4/libcli/raw/rawrequest.c6
-rw-r--r--source4/libcli/raw/rawtrans.c6
-rw-r--r--source4/libcli/raw/smb.h1
-rw-r--r--source4/libcli/resolve/host.c1
-rw-r--r--source4/libcli/resolve/nbtlist.c3
-rw-r--r--source4/libcli/resolve/resolve.c16
-rw-r--r--source4/libcli/security/config.mk21
-rw-r--r--source4/libcli/security/security.py2
-rw-r--r--source4/libcli/security/security_wrap.c65
-rw-r--r--source4/libcli/security/tests/bindings.py2
-rw-r--r--source4/libcli/smb2/break.c74
-rw-r--r--source4/libcli/smb2/config.mk31
-rw-r--r--source4/libcli/smb2/connect.c18
-rw-r--r--source4/libcli/smb2/create.c98
-rw-r--r--source4/libcli/smb2/find.c2
-rw-r--r--source4/libcli/smb2/flush.c6
-rw-r--r--source4/libcli/smb2/lock.c24
-rw-r--r--source4/libcli/smb2/read.c13
-rw-r--r--source4/libcli/smb2/request.c33
-rw-r--r--source4/libcli/smb2/session.c4
-rw-r--r--source4/libcli/smb2/smb2.h20
-rw-r--r--source4/libcli/smb2/transport.c43
-rw-r--r--source4/libcli/smb2/util.c200
-rw-r--r--source4/libcli/smb_composite/connect.c89
-rw-r--r--source4/libcli/smb_composite/fetchfile.c2
-rw-r--r--source4/libcli/smb_composite/fsinfo.c2
-rw-r--r--source4/libcli/smb_composite/sesssetup.c2
-rw-r--r--source4/libcli/smb_composite/smb2.c371
-rw-r--r--source4/libcli/smb_composite/smb_composite.h5
-rw-r--r--source4/libcli/swig/libcli_nbt.py2
-rw-r--r--source4/libcli/swig/libcli_nbt_wrap.c73
-rw-r--r--source4/libcli/swig/libcli_smb.py2
-rw-r--r--source4/libcli/swig/libcli_smb_wrap.c65
-rw-r--r--source4/libcli/wbclient/config.mk3
-rw-r--r--source4/libcli/wrepl/winsrepl.c6
62 files changed, 1903 insertions, 605 deletions
diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk
index f786c71469..498c2af258 100644
--- a/source4/libcli/auth/config.mk
+++ b/source4/libcli/auth/config.mk
@@ -1,16 +1,17 @@
#################################
# Start SUBSYSTEM LIBCLI_AUTH
[SUBSYSTEM::LIBCLI_AUTH]
-PRIVATE_PROTO_HEADER = proto.h
-OBJ_FILES = credentials.o \
- session.o \
- smbencrypt.o \
- smbdes.o
PUBLIC_DEPENDENCIES = \
MSRPC_PARSE \
LIBSAMBA-HOSTCONFIG
# End SUBSYSTEM LIBCLI_AUTH
#################################
+LIBCLI_AUTH_OBJ_FILES = $(addprefix $(libclisrcdir)/auth/, \
+ credentials.o \
+ session.o \
+ smbencrypt.o \
+ smbdes.o)
-PUBLIC_HEADERS += libcli/auth/credentials.h
+PUBLIC_HEADERS += $(libclisrcdir)/auth/credentials.h
+$(eval $(call proto_header_template,$(libclisrcdir)/auth/proto.h,$(LIBCLI_AUTH_OBJ_FILES:.o=.c)))
diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c
index d10eeb8ffd..860bd358d5 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);
@@ -599,10 +595,12 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
struct cldap_netlogon *io)
{
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;
@@ -619,18 +617,15 @@ 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,
- &io->out.netlogon,
- io->in.version & 0xF,
- (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n",
- SVAL(data->data, 0)));
- dump_data(10, data->data, data->length);
- return ndr_map_error2ntstatus(ndr_err);
+ status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience,
+ &io->out.netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (io->in.map_response) {
+ map_netlogon_samlogon_response(&io->out.netlogon);
}
-
return NT_STATUS_OK;
}
@@ -705,25 +700,20 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
uint32_t message_id,
struct socket_address *src,
uint32_t version,
- union nbt_cldap_netlogon *netlogon)
+ struct netlogon_samlogon_response *netlogon)
{
NTSTATUS status;
- enum ndr_err_code ndr_err;
struct cldap_reply reply;
struct ldap_SearchResEntry response;
struct ldap_Result result;
TALLOC_CTX *tmp_ctx = talloc_new(cldap);
DATA_BLOB blob;
- ndr_err = ndr_push_union_blob(&blob, tmp_ctx,
- cldap->iconv_convenience,
- netlogon, version & 0xF,
- (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
+ status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience,
+ netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
-
reply.messageid = message_id;
reply.dest = src;
reply.response = &response;
diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h
index eb0191d0f4..7c2daf0ca2 100644
--- a/source4/libcli/cldap/cldap.h
+++ b/source4/libcli/cldap/cldap.h
@@ -20,7 +20,7 @@
*/
#include "lib/util/asn1.h"
-#include "librpc/gen_ndr/nbt.h"
+#include "libcli/netlogon.h"
struct ldap_message;
@@ -161,9 +161,10 @@ struct cldap_netlogon {
const char *domain_sid;
int acct_control;
uint32_t version;
+ bool map_response;
} in;
struct {
- union nbt_cldap_netlogon netlogon;
+ struct netlogon_samlogon_response netlogon;
} out;
};
@@ -178,4 +179,4 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
uint32_t message_id,
struct socket_address *src,
uint32_t version,
- union nbt_cldap_netlogon *netlogon);
+ struct netlogon_samlogon_response *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/clifile.c b/source4/libcli/clifile.c
index e59b7f9af3..2cf174060b 100644
--- a/source4/libcli/clifile.c
+++ b/source4/libcli/clifile.c
@@ -650,7 +650,8 @@ NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path)
/****************************************************************************
Query disk space.
****************************************************************************/
-NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, int *bsize, int *total, int *avail)
+NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, uint32_t *bsize,
+ uint64_t *total, uint64_t *avail)
{
union smb_fsinfo fsinfo_parms;
TALLOC_CTX *mem_ctx;
@@ -658,12 +659,12 @@ NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, int *bsize, int *total, int *a
mem_ctx = talloc_init("smbcli_dskattr");
- fsinfo_parms.dskattr.level = RAW_QFS_DSKATTR;
+ fsinfo_parms.dskattr.level = RAW_QFS_SIZE_INFO;
status = smb_raw_fsinfo(tree, mem_ctx, &fsinfo_parms);
if (NT_STATUS_IS_OK(status)) {
- *bsize = fsinfo_parms.dskattr.out.block_size;
- *total = fsinfo_parms.dskattr.out.units_total;
- *avail = fsinfo_parms.dskattr.out.units_free;
+ *bsize = fsinfo_parms.size_info.out.bytes_per_sector * fsinfo_parms.size_info.out.sectors_per_unit;
+ *total = fsinfo_parms.size_info.out.total_alloc_units;
+ *avail = fsinfo_parms.size_info.out.avail_alloc_units;
}
talloc_free(mem_ctx);
diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c
index 26169e7838..3e3f224f47 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;
}
@@ -65,6 +69,17 @@ _PUBLIC_ NTSTATUS composite_wait(struct composite_context *c)
return c->status;
}
+/*
+ block until a composite function has completed, then return the status.
+ Free the composite context before returning
+*/
+_PUBLIC_ NTSTATUS composite_wait_free(struct composite_context *c)
+{
+ NTSTATUS status = composite_wait(c);
+ talloc_free(c);
+ return status;
+}
+
/*
callback from composite_done() and composite_error()
@@ -90,6 +105,12 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te,
_PUBLIC_ void composite_error(struct composite_context *ctx, NTSTATUS status)
{
+ /* you are allowed to pass NT_STATUS_OK to composite_error(), in which
+ case it is equivalent to composite_done() */
+ if (NT_STATUS_IS_OK(status)) {
+ composite_done(ctx);
+ return;
+ }
if (!ctx->used_wait && !ctx->async.fn) {
event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);
}
@@ -183,7 +204,7 @@ _PUBLIC_ void composite_continue_smb2(struct composite_context *ctx,
{
if (composite_nomem(new_req, ctx)) return;
new_req->async.fn = continuation;
- new_req->async.private = private_data;
+ new_req->async.private_data = private_data;
}
_PUBLIC_ void composite_continue_nbt(struct composite_context *ctx,
diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h
index f1bed20361..28cd6a88dc 100644
--- a/source4/libcli/composite/composite.h
+++ b/source4/libcli/composite/composite.h
@@ -101,6 +101,7 @@ bool composite_is_ok(struct composite_context *ctx);
void composite_done(struct composite_context *ctx);
void composite_error(struct composite_context *ctx, NTSTATUS status);
NTSTATUS composite_wait(struct composite_context *c);
+NTSTATUS composite_wait_free(struct composite_context *c);
#endif /* __COMPOSITE_H__ */
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index 0c00fa2740..b24f3eb4af 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -4,150 +4,174 @@ mkinclude security/config.mk
mkinclude wbclient/config.mk
[SUBSYSTEM::LIBSAMBA-ERRORS]
-OBJ_FILES = util/doserr.o \
- util/errormap.o \
- util/nterr.o \
+LIBSAMBA-ERRORS_OBJ_FILES = $(addprefix $(libclisrcdir)/util/, doserr.o errormap.o nterr.o)
-PUBLIC_HEADERS += $(addprefix libcli/, util/error.h util/ntstatus.h util/doserr.h util/werror.h)
+PUBLIC_HEADERS += $(addprefix $(libclisrcdir)/, util/error.h util/ntstatus.h util/doserr.h util/werror.h)
[SUBSYSTEM::LIBCLI_LSA]
-PRIVATE_PROTO_HEADER = util/clilsa.h
-OBJ_FILES = util/clilsa.o
PUBLIC_DEPENDENCIES = RPC_NDR_LSA
PRIVATE_DEPENDENCIES = LIBSECURITY
+LIBCLI_LSA_OBJ_FILES = $(libclisrcdir)/util/clilsa.o
+
+$(eval $(call proto_header_template,$(libclisrcdir)/util/clilsa.h,$(LIBCLI_LSA_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::LIBCLI_COMPOSITE]
-PRIVATE_PROTO_HEADER = composite/proto.h
-OBJ_FILES = \
- composite/composite.o
PUBLIC_DEPENDENCIES = LIBEVENTS
+LIBCLI_COMPOSITE_OBJ_FILES = $(libclisrcdir)/composite/composite.o
+$(eval $(call proto_header_template,$(libclisrcdir)/composite/proto.h,$(LIBCLI_COMPOSITE_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::LIBCLI_SMB_COMPOSITE]
-PRIVATE_PROTO_HEADER = smb_composite/proto.h
-OBJ_FILES = \
- smb_composite/loadfile.o \
- smb_composite/savefile.o \
- smb_composite/connect.o \
- smb_composite/sesssetup.o \
- smb_composite/fetchfile.o \
- smb_composite/appendacl.o \
- smb_composite/fsinfo.o
PUBLIC_DEPENDENCIES = LIBCLI_COMPOSITE CREDENTIALS gensec LIBCLI_RESOLVE
+LIBCLI_SMB_COMPOSITE_OBJ_FILES = $(addprefix $(libclisrcdir)/smb_composite/, \
+ loadfile.o \
+ savefile.o \
+ connect.o \
+ sesssetup.o \
+ fetchfile.o \
+ appendacl.o \
+ fsinfo.o \
+ smb2.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBCLI_SMB_COMPOSITE_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::NDR_NBT_BUF]
-PRIVATE_PROTO_HEADER = nbt/nbtname.h
-OBJ_FILES = nbt/nbtname.o
+
+NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o
+
+$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c)))
[SUBSYSTEM::LIBCLI_NBT]
-#VERSION = 0.0.1
-#SO_VERSION = 0
-PRIVATE_PROTO_HEADER = nbt/nbt_proto.h
-OBJ_FILES = \
- nbt/nbtsocket.o \
- nbt/namequery.o \
- nbt/nameregister.o \
- nbt/namerefresh.o \
- nbt/namerelease.o
PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \
NDR_SECURITY samba-socket LIBSAMBA-UTIL
+LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \
+ nbtsocket.o \
+ namequery.o \
+ nameregister.o \
+ namerefresh.o \
+ namerelease.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c)))
+
+[SUBSYSTEM::LIBCLI_NDR_NETLOGON]
+PUBLIC_DEPENDENCIES = LIBNDR \
+ NDR_SECURITY
+
+LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix libcli/, \
+ ndr_netlogon.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/ndr_netlogon_proto.h,$(LIBCLI_NDR_NETLOGON_OBJ_FILES:.o=.c)))
+
+[SUBSYSTEM::LIBCLI_NETLOGON]
+PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL LIBCLI_NDR_NETLOGON
+
+LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \
+ netlogon.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c)))
+
[PYTHON::python_libcli_nbt]
-SWIG_FILE = swig/libcli_nbt.i
+LIBRARY_REALNAME = samba/_libcli_nbt.$(SHLIBEXT)
PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG
+python_libcli_nbt_OBJ_FILES = $(libclisrcdir)/swig/libcli_nbt_wrap.o
+
+$(eval $(call python_py_module_template,samba/nbt.py,$(libclisrcdir)/swig/libcli_nbt.py))
+
+$(python_libcli_nbt_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)
+
[PYTHON::python_libcli_smb]
-SWIG_FILE = swig/libcli_smb.i
+LIBRARY_REALNAME = samba/_libcli_smb.$(SHLIBEXT)
PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG
+python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o
+
+$(eval $(call python_py_module_template,samba/smb.py,$(libclisrcdir)/swig/libcli_smb.py))
+
+$(python_libcli_smb_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)
+
+
[SUBSYSTEM::LIBCLI_DGRAM]
-OBJ_FILES = \
- dgram/dgramsocket.o \
- dgram/mailslot.o \
- dgram/netlogon.o \
- dgram/ntlogon.o \
- dgram/browse.o
-PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE
+PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON
+
+LIBCLI_DGRAM_OBJ_FILES = $(addprefix $(libclisrcdir)/dgram/, \
+ dgramsocket.o \
+ mailslot.o \
+ netlogon.o \
+ browse.o)
[SUBSYSTEM::LIBCLI_CLDAP]
-OBJ_FILES = cldap/cldap.o
PUBLIC_DEPENDENCIES = LIBCLI_LDAP
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB
+PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON
-# PUBLIC_HEADERS += libcli/cldap/cldap.h
+LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o
+# PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h
[SUBSYSTEM::LIBCLI_WREPL]
-PRIVATE_PROTO_HEADER = wrepl/winsrepl_proto.h
-OBJ_FILES = \
- wrepl/winsrepl.o
PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \
LIBPACKET LIBNDR
+LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o
+
+$(eval $(call proto_header_template,$(libclisrcdir)/wrepl/winsrepl_proto.h,$(LIBCLI_WREPL_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::LIBCLI_RESOLVE]
-PRIVATE_PROTO_HEADER = resolve/proto.h
-OBJ_FILES = \
- resolve/resolve.o
PUBLIC_DEPENDENCIES = NDR_NBT
+LIBCLI_RESOLVE_OBJ_FILES = $(libclisrcdir)/resolve/resolve.o
+
+$(eval $(call proto_header_template,$(libclisrcdir)/resolve/proto.h,$(LIBCLI_RESOLVE_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::LP_RESOLVE]
-PRIVATE_PROTO_HEADER = resolve/lp_proto.h
-OBJ_FILES = \
- resolve/bcast.o \
- resolve/nbtlist.o \
- resolve/wins.o \
- resolve/host.o \
- resolve/resolve_lp.o
PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF
+LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \
+ bcast.o nbtlist.o wins.o \
+ host.o resolve_lp.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::LIBCLI_FINDDCS]
-PRIVATE_PROTO_HEADER = finddcs.h
-OBJ_FILES = \
- finddcs.o
PUBLIC_DEPENDENCIES = LIBCLI_NBT MESSAGING
+LIBCLI_FINDDCS_OBJ_FILES = $(libclisrcdir)/finddcs.o
+
+$(eval $(call proto_header_template,$(libclisrcdir)/finddcs.h,$(LIBCLI_FINDDCS_OBJ_FILES:.o=.c)))
+
[SUBSYSTEM::LIBCLI_SMB]
-PRIVATE_PROTO_HEADER = libcli_proto.h
-OBJ_FILES = clireadwrite.o \
+PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \
+ LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \
+ LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket
+
+LIBCLI_SMB_OBJ_FILES = $(addprefix $(libclisrcdir)/, \
+ clireadwrite.o \
cliconnect.o \
clifile.o \
clilist.o \
clitrans2.o \
climessage.o \
- clideltree.o
-PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBSAMBA-ERRORS LIBCLI_AUTH \
- LIBCLI_SMB_COMPOSITE LIBCLI_NBT LIBSECURITY LIBCLI_RESOLVE \
- LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba-socket
+ clideltree.o)
+$(eval $(call proto_header_template,$(libclisrcdir)/libcli_proto.h,$(LIBCLI_SMB_OBJ_FILES:.o=.c)))
-# PUBLIC_HEADERS += libcli/libcli.h
+# PUBLIC_HEADERS += $(libclisrcdir)/libcli.h
[SUBSYSTEM::LIBCLI_RAW]
-PRIVATE_PROTO_HEADER = raw/raw_proto.h
PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR
#LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT)
PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS
-OBJ_FILES = raw/rawfile.o \
- raw/smb_signing.o \
- raw/clisocket.o \
- raw/clitransport.o \
- raw/clisession.o \
- raw/clitree.o \
- raw/clierror.o \
- raw/rawrequest.o \
- raw/rawreadwrite.o \
- raw/rawsearch.o \
- raw/rawsetfileinfo.o \
- raw/raweas.o \
- raw/rawtrans.o \
- raw/clioplock.o \
- raw/rawnegotiate.o \
- raw/rawfsinfo.o \
- raw/rawfileinfo.o \
- raw/rawnotify.o \
- raw/rawioctl.o \
- raw/rawacl.o \
- raw/rawdate.o \
- raw/rawlpq.o \
- raw/rawshadow.o
+
+LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o clisocket.o \
+ clitransport.o clisession.o clitree.o clierror.o rawrequest.o \
+ rawreadwrite.o rawsearch.o rawsetfileinfo.o raweas.o rawtrans.o \
+ clioplock.o rawnegotiate.o rawfsinfo.o rawfileinfo.o rawnotify.o \
+ rawioctl.o rawacl.o rawdate.o rawlpq.o rawshadow.o)
+
+
+$(eval $(call proto_header_template,$(libclisrcdir)/raw/raw_proto.h,$(LIBCLI_RAW_OBJ_FILES:.o=.c)))
mkinclude smb2/config.mk
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/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h
index 707cca8cc5..e1209e7a54 100644
--- a/source4/libcli/dgram/libdgram.h
+++ b/source4/libcli/dgram/libdgram.h
@@ -19,7 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "librpc/gen_ndr/nbt.h"
+#include "libcli/netlogon.h"
/*
a datagram name request
@@ -121,33 +121,23 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock,
NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock,
struct nbt_name *dest_name,
struct socket_address *dest,
+ const char *mailslot_name,
struct nbt_name *src_name,
struct nbt_netlogon_packet *request);
NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock,
struct nbt_dgram_packet *request,
const char *my_netbios_name,
const char *mailslot_name,
- struct nbt_netlogon_packet *reply);
-NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_netlogon_packet *netlogon);
-
-NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock,
- enum dgram_msg_type msg_type,
- struct nbt_name *dest_name,
- struct socket_address *dest,
- struct nbt_name *src_name,
- struct nbt_ntlogon_packet *request);
-NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock,
- struct nbt_dgram_packet *request,
- const char *my_netbios_name,
- const char *mailslot_name,
- struct nbt_ntlogon_packet *reply);
-NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_ntlogon_packet *ntlogon);
+ struct nbt_netlogon_response *reply);
+NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_packet *netlogon);
+
+NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_response *netlogon);
NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock,
struct nbt_name *dest_name,
diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c
index 5c7dedc7bb..b37d4a2ee6 100644
--- a/source4/libcli/dgram/netlogon.c
+++ b/source4/libcli/dgram/netlogon.c
@@ -32,6 +32,7 @@
NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock,
struct nbt_name *dest_name,
struct socket_address *dest,
+ const char *mailslot,
struct nbt_name *src_name,
struct nbt_netlogon_packet *request)
{
@@ -51,7 +52,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock,
status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE,
- NBT_MAILSLOT_NETLOGON,
+ mailslot,
dest_name, dest,
src_name, &blob);
talloc_free(tmp_ctx);
@@ -66,22 +67,18 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock,
struct nbt_dgram_packet *request,
const char *my_netbios_name,
const char *mailslot_name,
- struct nbt_netlogon_packet *reply)
+ struct nbt_netlogon_response *reply)
{
NTSTATUS status;
- enum ndr_err_code ndr_err;
DATA_BLOB blob;
TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
struct nbt_name myname;
struct socket_address *dest;
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx,
- dgmsock->iconv_convenience,
- reply,
- (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
+ status = push_nbt_netlogon_response(&blob, tmp_ctx, dgmsock->iconv_convenience,
+ reply);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
make_nbt_name_client(&myname, my_netbios_name);
@@ -106,10 +103,10 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock,
/*
parse a netlogon response. The packet must be a valid mailslot packet
*/
-NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_netlogon_packet *netlogon)
+NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_packet *netlogon)
{
DATA_BLOB data = dgram_mailslot_data(dgram);
enum ndr_err_code ndr_err;
@@ -127,3 +124,23 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot,
}
return NT_STATUS_OK;
}
+
+/*
+ parse a netlogon response. The packet must be a valid mailslot packet
+*/
+NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot,
+ TALLOC_CTX *mem_ctx,
+ struct nbt_dgram_packet *dgram,
+ struct nbt_netlogon_response *netlogon)
+{
+ NTSTATUS status;
+ DATA_BLOB data = dgram_mailslot_data(dgram);
+
+ status = pull_nbt_netlogon_response(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c
deleted file mode 100644
index 7b26ed7c00..0000000000
--- a/source4/libcli/dgram/ntlogon.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- handling for ntlogon dgram requests
-
- Copyright (C) Andrew Tridgell 2005
-
- 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/dgram/libdgram.h"
-#include "lib/socket/socket.h"
-#include "libcli/resolve/resolve.h"
-#include "librpc/gen_ndr/ndr_nbt.h"
-#include "param/param.h"
-
-/*
- send a ntlogon mailslot request
-*/
-NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock,
- enum dgram_msg_type msg_type,
- struct nbt_name *dest_name,
- struct socket_address *dest,
- struct nbt_name *src_name,
- struct nbt_ntlogon_packet *request)
-{
- NTSTATUS status;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
-
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience,
- request,
- (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
- }
-
-
- status = dgram_mailslot_send(dgmsock, msg_type,
- NBT_MAILSLOT_NTLOGON,
- dest_name, dest,
- src_name, &blob);
- talloc_free(tmp_ctx);
- return status;
-}
-
-
-/*
- send a ntlogon mailslot reply
-*/
-NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock,
- struct nbt_dgram_packet *request,
- const char *my_netbios_name,
- const char *mailslot_name,
- struct nbt_ntlogon_packet *reply)
-{
- NTSTATUS status;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
- struct nbt_name myname;
- struct socket_address *dest;
-
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply,
- (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(tmp_ctx);
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- make_nbt_name_client(&myname, my_netbios_name);
-
- dest = socket_address_from_strings(tmp_ctx,
- dgmsock->sock->backend_name,
- request->src_addr, request->src_port);
- if (!dest) {
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE,
- mailslot_name,
- &request->data.msg.source_name,
- dest,
- &myname, &blob);
- talloc_free(tmp_ctx);
- return status;
-}
-
-
-/*
- parse a ntlogon response. The packet must be a valid mailslot packet
-*/
-NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot,
- TALLOC_CTX *mem_ctx,
- struct nbt_dgram_packet *dgram,
- struct nbt_ntlogon_packet *ntlogon)
-{
- DATA_BLOB data = dgram_mailslot_data(dgram);
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, ntlogon,
- (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
- DEBUG(0,("Failed to parse ntlogon packet of length %d: %s\n",
- (int)data.length, nt_errstr(status)));
- if (DEBUGLVL(10)) {
- file_save("ntlogon.dat", data.data, data.length);
- }
- return status;
- }
- return NT_STATUS_OK;
-}
diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk
index 0c5236c138..02678eed7a 100644
--- a/source4/libcli/ldap/config.mk
+++ b/source4/libcli/ldap/config.mk
@@ -1,17 +1,18 @@
[SUBSYSTEM::LIBCLI_LDAP]
-PRIVATE_PROTO_HEADER = ldap_proto.h
-OBJ_FILES = ldap.o \
- ldap_client.o \
- ldap_bind.o \
- ldap_msg.o \
- ldap_ildap.o \
- ldap_controls.o
PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS LIBPACKET
PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba-socket NDR_SAMR LIBTLS ASN1_UTIL \
LDAP_ENCODE LIBNDR LP_RESOLVE gensec
-PUBLIC_HEADERS += libcli/ldap/ldap.h libcli/ldap/ldap_ndr.h
+LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \
+ ldap.o ldap_client.o ldap_bind.o \
+ ldap_msg.o ldap_ildap.o ldap_controls.o)
+
+
+PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h
+
+$(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c)))
[SUBSYSTEM::LDAP_ENCODE]
-OBJ_FILES = ldap_ndr.o
# FIXME PRIVATE_DEPENDENCIES = LIBLDB
+
+LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o
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/ndr_netlogon.c b/source4/libcli/ndr_netlogon.c
new file mode 100644
index 0000000000..504b3b02a7
--- /dev/null
+++ b/source4/libcli/ndr_netlogon.c
@@ -0,0 +1,209 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ CLDAP server structures
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 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/>.
+*/
+
+/* parser auto-generated by pidl, then hand-modified by abartlet */
+
+#include "includes.h"
+#include "libcli/netlogon.h"
+/* Manually modified to handle the dom_sid being optional based on if it is present or all zero */
+enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_REQUEST *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->request_count));
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->computer_name));
+ ndr->flags = _flags_save_string;
+ }
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->user_name));
+ ndr->flags = _flags_save_string;
+ }
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->mailslot_name));
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_push_samr_AcctFlags(ndr, NDR_SCALARS, r->acct_control));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_dom_sid0(&r->sid, ndr->flags)));
+ if (ndr_size_dom_sid0(&r->sid, ndr->flags)) {
+ struct ndr_push *_ndr_sid;
+ uint32_t _flags_save_DATA_BLOB = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4);
+ NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad));
+ ndr->flags = _flags_save_DATA_BLOB;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags)));
+ NDR_CHECK(ndr_push_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid));
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags)));
+ }
+ NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+/* Manually modified to handle the dom_sid being optional based on if it is present (size is non-zero) or not */
+enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_REQUEST *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->request_count));
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->computer_name));
+ ndr->flags = _flags_save_string;
+ }
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->user_name));
+ ndr->flags = _flags_save_string;
+ }
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->mailslot_name));
+ ndr->flags = _flags_save_string;
+ }
+ NDR_CHECK(ndr_pull_samr_AcctFlags(ndr, NDR_SCALARS, &r->acct_control));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sid_size));
+ if (r->sid_size) {
+ uint32_t _flags_save_DATA_BLOB = ndr->flags;
+ struct ndr_pull *_ndr_sid;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4);
+ NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad));
+ ndr->flags = _flags_save_DATA_BLOB;
+ NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sid, 0, r->sid_size));
+ NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid));
+ NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sid, 0, r->sid_size));
+ } else {
+ ZERO_STRUCT(r->sid);
+ }
+ NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+/* Manually modified to only push some parts of the structure if certain flags are set */
+enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_RESPONSE_EX *r)
+{
+ {
+ uint32_t _flags_save_STRUCT = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_netlogon_command(ndr, NDR_SCALARS, r->command));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->sbz));
+ NDR_CHECK(ndr_push_nbt_server_type(ndr, NDR_SCALARS, r->server_type));
+ NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->domain_uuid));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->forest));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->dns_domain));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_dns_name));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->domain));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->pdc_name));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->user_name));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->server_site));
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->client_site));
+ if (r->nt_version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
+ {
+ struct ndr_push *_ndr_sockaddr;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
+ NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr));
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sockaddr, 0, ndr_size_nbt_sockaddr(&r->sockaddr, ndr->flags)));
+ }
+ }
+ if (r->nt_version & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) {
+ NDR_CHECK(ndr_push_nbt_string(ndr, NDR_SCALARS, r->next_closest_site));
+ }
+ NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_push_GUID(ndr, NDR_BUFFERS, &r->domain_uuid));
+ }
+ ndr->flags = _flags_save_STRUCT;
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+/* Manually modified to only pull some parts of the structure if certain flags provided */
+enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_RESPONSE_EX *r,
+ uint32_t nt_version_flags)
+{
+ {
+ uint32_t _flags_save_STRUCT = ndr->flags;
+ ZERO_STRUCTP(r);
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_netlogon_command(ndr, NDR_SCALARS, &r->command));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->sbz));
+ NDR_CHECK(ndr_pull_nbt_server_type(ndr, NDR_SCALARS, &r->server_type));
+ NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->domain_uuid));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->forest));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->dns_domain));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_dns_name));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->domain));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->pdc_name));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->user_name));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->server_site));
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->client_site));
+ if (nt_version_flags & NETLOGON_NT_VERSION_5EX_WITH_IP) {
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sockaddr_size));
+ {
+ struct ndr_pull *_ndr_sockaddr;
+ NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_sockaddr, 0, r->sockaddr_size));
+ NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr, NDR_SCALARS|NDR_BUFFERS, &r->sockaddr));
+ NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_sockaddr, 0, r->sockaddr_size));
+ }
+ }
+ if (nt_version_flags & NETLOGON_NT_VERSION_WITH_CLOSEST_SITE) {
+ NDR_CHECK(ndr_pull_nbt_string(ndr, NDR_SCALARS, &r->next_closest_site));
+ }
+ NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr, NDR_SCALARS, &r->nt_version));
+ if (r->nt_version != nt_version_flags) {
+ return NDR_ERR_VALIDATE;
+ }
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lmnt_token));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->lm20_token));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_GUID(ndr, NDR_BUFFERS, &r->domain_uuid));
+ }
+ ndr->flags = _flags_save_STRUCT;
+ }
+ return NDR_ERR_SUCCESS;
+}
diff --git a/source4/libcli/netlogon.c b/source4/libcli/netlogon.c
new file mode 100644
index 0000000000..052d7cbc1e
--- /dev/null
+++ b/source4/libcli/netlogon.c
@@ -0,0 +1,239 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ CLDAP server structures
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 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/netlogon.h"
+
+NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct netlogon_samlogon_response *response)
+{
+ enum ndr_err_code ndr_err;
+ if (response->ntver == NETLOGON_NT_VERSION_1) {
+ ndr_err = ndr_push_struct_blob(data, mem_ctx,
+ iconv_convenience,
+ &response->nt4,
+ (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40);
+ } else if (response->ntver & NETLOGON_NT_VERSION_5EX) {
+ ndr_err = ndr_push_struct_blob(data, mem_ctx,
+ iconv_convenience,
+ &response->nt5_ex,
+ (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags);
+ } else if (response->ntver & NETLOGON_NT_VERSION_5) {
+ ndr_err = ndr_push_struct_blob(data, mem_ctx,
+ iconv_convenience,
+ &response->nt5,
+ (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE);
+ } else {
+ DEBUG(0, ("Asked to push unknown netlogon response type 0x%02x\n", response->ntver));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(2,("failed to push netlogon response of type 0x%02x\n",
+ response->ntver));
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct netlogon_samlogon_response *response)
+{
+ uint32_t ntver;
+ enum ndr_err_code ndr_err;
+
+ if (data->length < 8) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* lmnttoken */
+ if (SVAL(data->data, data->length - 4) != 0xffff) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ /* lm20token */
+ if (SVAL(data->data, data->length - 2) != 0xffff) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ ntver = IVAL(data->data, data->length - 8);
+
+ if (ntver == NETLOGON_NT_VERSION_1) {
+ ndr_err = ndr_pull_struct_blob_all(data, mem_ctx,
+ iconv_convenience,
+ &response->nt4,
+ (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40);
+ response->ntver = NETLOGON_NT_VERSION_1;
+ } else if (ntver & NETLOGON_NT_VERSION_5EX) {
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(data, mem_ctx, iconv_convenience);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(ndr, NDR_SCALARS|NDR_BUFFERS, &response->nt5_ex, ntver);
+ if (ndr->offset < ndr->data_size) {
+ ndr_err = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,
+ "not all bytes consumed ofs[%u] size[%u]",
+ ndr->offset, ndr->data_size);
+ }
+ response->ntver = NETLOGON_NT_VERSION_5EX;
+
+ } else if (ntver & NETLOGON_NT_VERSION_5) {
+ ndr_err = ndr_pull_struct_blob_all(data, mem_ctx,
+ iconv_convenience,
+ &response->nt5,
+ (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE);
+ response->ntver = NETLOGON_NT_VERSION_5;
+ } else {
+ DEBUG(2,("failed to parse netlogon response of type 0x%02x - unknown response type\n",
+ ntver));
+ dump_data(10, data->data, data->length);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(2,("failed to parse netlogon response of type 0x%02x\n",
+ ntver));
+ dump_data(10, data->data, data->length);
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+ return NT_STATUS_OK;
+}
+
+void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response)
+{
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX response_5_ex;
+ switch (response->ntver) {
+ case NETLOGON_NT_VERSION_5EX:
+ break;
+ case NETLOGON_NT_VERSION_5:
+ ZERO_STRUCT(response_5_ex);
+ response_5_ex.command = response->nt5.command;
+ response_5_ex.pdc_name = response->nt5.pdc_name;
+ response_5_ex.user_name = response->nt5.user_name;
+ response_5_ex.domain = response->nt5.domain_name;
+ response_5_ex.domain_uuid = response->nt5.domain_uuid;
+ response_5_ex.forest = response->nt5.forest;
+ response_5_ex.dns_domain = response->nt5.dns_domain;
+ response_5_ex.pdc_dns_name = response->nt5.pdc_dns_name;
+ response_5_ex.sockaddr.pdc_ip = response->nt5.pdc_ip;
+ response_5_ex.server_type = response->nt5.server_type;
+ response_5_ex.nt_version = response->nt5.nt_version;
+ response_5_ex.lmnt_token = response->nt5.lmnt_token;
+ response_5_ex.lm20_token = response->nt5.lm20_token;
+ response->ntver = NETLOGON_NT_VERSION_5EX;
+ response->nt5_ex = response_5_ex;
+ break;
+
+ case NETLOGON_NT_VERSION_1:
+ ZERO_STRUCT(response_5_ex);
+ response_5_ex.command = response->nt4.command;
+ response_5_ex.pdc_name = response->nt4.server;
+ response_5_ex.user_name = response->nt4.user_name;
+ response_5_ex.domain = response->nt4.domain;
+ response_5_ex.nt_version = response->nt4.nt_version;
+ response_5_ex.lmnt_token = response->nt4.lmnt_token;
+ response_5_ex.lm20_token = response->nt4.lm20_token;
+ response->ntver = NETLOGON_NT_VERSION_5EX;
+ response->nt5_ex = response_5_ex;
+ break;
+ }
+ return;
+}
+
+NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct nbt_netlogon_response *response)
+{
+ NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ enum ndr_err_code ndr_err;
+ switch (response->response_type) {
+ case NETLOGON_GET_PDC:
+ ndr_err = ndr_push_struct_blob(data, mem_ctx, iconv_convenience, &response->get_pdc,
+ (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response_from_pdc);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n",
+ (int)data->length, nt_errstr(status)));
+ if (DEBUGLVL(10)) {
+ file_save("netlogon.dat", data->data, data->length);
+ }
+ return status;
+ }
+ status = NT_STATUS_OK;
+ break;
+ case NETLOGON_SAMLOGON:
+ status = push_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon);
+ break;
+ }
+ return status;
+}
+
+
+NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct nbt_netlogon_response *response)
+{
+ NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ enum netlogon_command command;
+ enum ndr_err_code ndr_err;
+ if (data->length < 4) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ command = SVAL(data->data, 0);
+
+ switch (command) {
+ case NETLOGON_RESPONSE_FROM_PDC:
+ ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, iconv_convenience, &response->get_pdc,
+ (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response_from_pdc);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n",
+ (int)data->length, nt_errstr(status)));
+ if (DEBUGLVL(10)) {
+ file_save("netlogon.dat", data->data, data->length);
+ }
+ return status;
+ }
+ status = NT_STATUS_OK;
+ response->response_type = NETLOGON_GET_PDC;
+ break;
+ case LOGON_SAM_LOGON_RESPONSE:
+ case LOGON_SAM_LOGON_PAUSE_RESPONSE:
+ case LOGON_SAM_LOGON_USER_UNKNOWN:
+ case LOGON_SAM_LOGON_RESPONSE_EX:
+ case LOGON_SAM_LOGON_PAUSE_RESPONSE_EX:
+ case LOGON_SAM_LOGON_USER_UNKNOWN_EX:
+ status = pull_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon);
+ response->response_type = NETLOGON_SAMLOGON;
+ break;
+
+ /* These levels are queries, not responses */
+ case LOGON_PRIMARY_QUERY:
+ case NETLOGON_ANNOUNCE_UAS:
+ case LOGON_SAM_LOGON_REQUEST:
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ return status;
+
+}
diff --git a/source4/libcli/netlogon.h b/source4/libcli/netlogon.h
new file mode 100644
index 0000000000..177ed3a514
--- /dev/null
+++ b/source4/libcli/netlogon.h
@@ -0,0 +1,54 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ CLDAP server structures
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 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/>.
+*/
+
+#ifndef __LIBCLI_NETLOGON_H__
+#define __LIBCLI_NETLOGON_H__
+
+#include "librpc/gen_ndr/ndr_nbt.h"
+
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "librpc/gen_ndr/ndr_svcctl.h"
+#include "librpc/gen_ndr/ndr_samr.h"
+
+struct netlogon_samlogon_response
+{
+ uint32_t ntver;
+ union {
+ struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4;
+ struct NETLOGON_SAM_LOGON_RESPONSE nt5;
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex;
+ };
+
+};
+
+struct nbt_netlogon_response
+{
+ enum {NETLOGON_GET_PDC, NETLOGON_SAMLOGON} response_type;
+ union {
+ struct nbt_netlogon_response_from_pdc get_pdc;
+ struct netlogon_samlogon_response samlogon;
+ };
+};
+
+#include "libcli/netlogon_proto.h"
+#include "libcli/ndr_netlogon_proto.h"
+#endif /* __CLDAP_SERVER_PROTO_H__ */
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/clitree.c b/source4/libcli/raw/clitree.c
index d5075f9271..15cd70833c 100644
--- a/source4/libcli/raw/clitree.c
+++ b/source4/libcli/raw/clitree.c
@@ -193,6 +193,11 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
io.in.service_type = service_type;
io.in.credentials = credentials;
io.in.fallback_to_anonymous = false;
+
+ /* This workgroup gets sent out by the SPNEGO session setup.
+ * I don't know of any servers that look at it, so we might
+ * hardcode it to "" some day, when the war on global_loadparm
+ * is complete -- abartlet 2008-04-28 */
io.in.workgroup = lp_workgroup(global_loadparm);
io.in.options = *options;
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 3965c58204..bae0e67b02 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -684,7 +684,8 @@ union smb_fileinfo {
uint32_t ea_size;
uint32_t access_mask;
uint64_t position;
- uint64_t mode;
+ uint32_t mode;
+ uint32_t alignment_requirement;
struct smb_wire_string fname;
} out;
} all_info2;
@@ -1587,6 +1588,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 +1715,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,16 +1863,16 @@ 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 */
-#define RAW_LOCK_GENERIC RAW_LOCK_LOCKX
+#define RAW_LOCK_GENERIC RAW_LOCK_LOCKX
/* union for lock() backend call
*/
union smb_lock {
- /* SMBlockingX (and generic) interface */
+ /* SMBlockingX and generic interface */
struct {
enum smb_lock_level level;
struct {
@@ -1870,7 +1887,7 @@ union smb_lock {
uint64_t count;
} *locks; /* unlocks are first in the arrray */
} in;
- } lockx, generic;
+ } generic, lockx;
/* SMBlock and SMBunlock interface */
struct {
@@ -1890,25 +1907,42 @@ union smb_lock {
/* static body buffer 48 (0x30) bytes */
/* uint16_t buffer_code; 0x30 */
- uint16_t unknown1; /* must be 0x0001 */
- uint32_t unknown2;
+ uint16_t lock_count;
+ uint32_t reserved;
/* struct smb2_handle handle; */
- uint64_t offset;
- uint64_t count;
- uint32_t unknown5;
+ struct smb2_lock_element {
+ uint64_t offset;
+ uint64_t length;
+/* these flags are the same as the SMB2 lock flags */
#define SMB2_LOCK_FLAG_NONE 0x00000000
#define SMB2_LOCK_FLAG_SHARED 0x00000001
-#define SMB2_LOCK_FLAG_EXCLUSIV 0x00000002
+#define SMB2_LOCK_FLAG_EXCLUSIVE 0x00000002
#define SMB2_LOCK_FLAG_UNLOCK 0x00000004
-#define SMB2_LOCK_FLAG_NO_PENDING 0x00000010
- uint32_t flags;
+#define SMB2_LOCK_FLAG_FAIL_IMMEDIATELY 0x00000010
+ uint32_t flags;
+ uint32_t reserved;
+ } *locks;
} in;
struct {
/* static body buffer 4 (0x04) bytes */
/* uint16_t buffer_code; 0x04 */
- uint16_t unknown1;
+ uint16_t reserved;
} 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;
};
@@ -2123,8 +2157,12 @@ union smb_flush {
enum smb_flush_level level;
struct {
union smb_handle file;
- uint32_t unknown;
+ uint16_t reserved1;
+ uint32_t reserved2;
} in;
+ struct {
+ uint16_t reserved;
+ } out;
} smb2;
};
@@ -2323,10 +2361,11 @@ union smb_search_first {
#define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25
#define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26
-/* flags for RAW_FILEINFO_SMB2_ALL_EAS */
+/* flags for SMB2 find */
#define SMB2_CONTINUE_FLAG_RESTART 0x01
#define SMB2_CONTINUE_FLAG_SINGLE 0x02
-#define SMB2_CONTINUE_FLAG_NEW 0x10
+#define SMB2_CONTINUE_FLAG_INDEX 0x04
+#define SMB2_CONTINUE_FLAG_REOPEN 0x10
/* SMB2 Find */
struct smb2_find {
@@ -2339,7 +2378,7 @@ union smb_search_first {
/* uint16_t buffer_code; 0x21 = 0x20 + 1 */
uint8_t level;
uint8_t continue_flags; /* SMB2_CONTINUE_FLAG_* */
- uint32_t unknown; /* perhaps a continue token? */
+ uint32_t file_index;
/* struct smb2_handle handle; */
/* uint16_t pattern_ofs; */
/* uint16_t pattern_size; */
diff --git a/source4/libcli/raw/raweas.c b/source4/libcli/raw/raweas.c
index 8ea8e621c9..07b517ade3 100644
--- a/source4/libcli/raw/raweas.c
+++ b/source4/libcli/raw/raweas.c
@@ -54,13 +54,13 @@ static uint_t ea_name_list_size(uint_t num_names, struct ea_name *eas)
This assumes the names are strict ascii, which should be a
reasonable assumption
*/
-size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas)
+size_t ea_list_size_chained(uint_t num_eas, struct ea_struct *eas, unsigned alignment)
{
uint_t total = 0;
int i;
for (i=0;i<num_eas;i++) {
uint_t len = 8 + strlen(eas[i].name.s)+1 + eas[i].value.length;
- len = (len + 3) & ~3;
+ len = (len + (alignment-1)) & ~(alignment-1);
total += len;
}
return total;
@@ -96,14 +96,15 @@ void ea_put_list(uint8_t *data, uint_t num_eas, struct ea_struct *eas)
put a chained ea_list into a pre-allocated buffer - buffer must be
at least of size ea_list_size()
*/
-void ea_put_list_chained(uint8_t *data, uint_t num_eas, struct ea_struct *eas)
+void ea_put_list_chained(uint8_t *data, uint_t num_eas, struct ea_struct *eas,
+ unsigned alignment)
{
int i;
for (i=0;i<num_eas;i++) {
uint_t nlen = strlen(eas[i].name.s);
uint32_t len = 8+nlen+1+eas[i].value.length;
- uint_t pad = ((len + 3) & ~3) - len;
+ uint_t pad = ((len + (alignment-1)) & ~(alignment-1)) - len;
if (i == num_eas-1) {
SIVAL(data, 0, 0);
} else {
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index 3c5c1b742b..d39c61551b 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -314,14 +314,14 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr
if (parms->ntcreatex.in.ea_list) {
uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas,
- parms->ntcreatex.in.ea_list->eas);
+ parms->ntcreatex.in.ea_list->eas, 4);
ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
if (ea_blob.data == NULL) {
return NULL;
}
ea_put_list_chained(ea_blob.data,
parms->ntcreatex.in.ea_list->num_eas,
- parms->ntcreatex.in.ea_list->eas);
+ parms->ntcreatex.in.ea_list->eas, 4);
}
nt.in.params = data_blob_talloc(mem_ctx, NULL, 53);
diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c
index 71900be49c..0ea5a93606 100644
--- a/source4/libcli/raw/rawfileinfo.c
+++ b/source4/libcli/raw/rawfileinfo.c
@@ -243,7 +243,8 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_
parms->all_info2.out.ea_size = IVAL(blob->data, 0x48);
parms->all_info2.out.access_mask = IVAL(blob->data, 0x4C);
parms->all_info2.out.position = BVAL(blob->data, 0x50);
- parms->all_info2.out.mode = BVAL(blob->data, 0x58);
+ parms->all_info2.out.mode = IVAL(blob->data, 0x58);
+ parms->all_info2.out.alignment_requirement = IVAL(blob->data, 0x5C);
smbcli_blob_pull_string(NULL, mem_ctx, blob,
&parms->all_info2.out.fname, 0x60, 0x64, STR_UNICODE);
return NT_STATUS_OK;
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/raw/smb.h b/source4/libcli/raw/smb.h
index e054ed6522..74869e8a45 100644
--- a/source4/libcli/raw/smb.h
+++ b/source4/libcli/raw/smb.h
@@ -370,6 +370,7 @@
#define FILE_ATTRIBUTE_OFFLINE 0x1000
#define FILE_ATTRIBUTE_NONINDEXED 0x2000
#define FILE_ATTRIBUTE_ENCRYPTED 0x4000
+#define FILE_ATTRIBUTE_ALL_MASK 0x7FFF
/* Flags - combined with attributes. */
#define FILE_FLAG_WRITE_THROUGH 0x80000000L
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..d89b50e430 100644
--- a/source4/libcli/resolve/resolve.c
+++ b/source4/libcli/resolve/resolve.c
@@ -136,19 +136,13 @@ 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) {
- composite_error(c, NT_STATUS_INVALID_PARAMETER);
- return c;
+ if (ctx == NULL || event_ctx == NULL) {
+ return NULL;
}
- 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/security/config.mk b/source4/libcli/security/config.mk
index 8c66df0325..f2883d1ede 100644
--- a/source4/libcli/security/config.mk
+++ b/source4/libcli/security/config.mk
@@ -1,13 +1,18 @@
[SUBSYSTEM::LIBSECURITY]
-PRIVATE_PROTO_HEADER = proto.h
-OBJ_FILES = security_token.o \
- security_descriptor.o \
- dom_sid.o \
- access_check.o \
- privilege.o \
- sddl.o
PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR
+LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \
+ security_token.o security_descriptor.o \
+ dom_sid.o access_check.o privilege.o sddl.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c)))
+
[PYTHON::swig_security]
-SWIG_FILE = security.i
+LIBRARY_REALNAME = samba/_security.$(SHLIBEXT)
PRIVATE_DEPENDENCIES = LIBSECURITY
+
+swig_security_OBJ_FILES = $(libclisrcdir)/security/security_wrap.o
+
+$(eval $(call python_py_module_template,samba/security.py,$(libclisrcdir)/security/security.py))
+
+$(swig_security_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)
diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py
index 10b263b27b..7e56e22cef 100644
--- a/source4/libcli/security/security.py
+++ b/source4/libcli/security/security.py
@@ -1,5 +1,5 @@
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.33
+# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c
index eb9e4c45d9..aabf6c27ee 100644
--- a/source4/libcli/security/security_wrap.c
+++ b/source4/libcli/security/security_wrap.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3.33
+ * Version 1.3.35
*
* This file is not intended to be easily readable and contains a number of
* coding conventions designed to improve portability and efficiency. Do not make
@@ -126,7 +126,7 @@
/* This should only be incremented when either the layout of swig_type_info changes,
or for whatever reason, the runtime changes incompatibly */
-#define SWIG_RUNTIME_VERSION "3"
+#define SWIG_RUNTIME_VERSION "4"
/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
#ifdef SWIG_TYPE_TABLE
@@ -161,6 +161,7 @@
/* Flags for pointer conversions */
#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
/* Flags for new pointer objects */
#define SWIG_POINTER_OWN 0x1
@@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) {
extern "C" {
#endif
-typedef void *(*swig_converter_func)(void *);
+typedef void *(*swig_converter_func)(void *, int *);
typedef struct swig_type_info *(*swig_dycast_func)(void **);
-/* Structure to store inforomation on one type */
+/* Structure to store information on one type */
typedef struct swig_type_info {
const char *name; /* mangled name of this type */
const char *str; /* human readable name of this type */
@@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
Cast a pointer up an inheritance hierarchy
*/
SWIGRUNTIMEINLINE void *
-SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
- return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
}
/*
@@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg)
Py_DECREF(old_str);
Py_DECREF(value);
} else {
- PyErr_Format(PyExc_RuntimeError, mesg);
+ PyErr_SetString(PyExc_RuntimeError, mesg);
}
}
@@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v)
{
PySwigObject *sobj = (PySwigObject *) v;
PyObject *next = sobj->next;
- if (sobj->own) {
+ if (sobj->own == SWIG_POINTER_OWN) {
swig_type_info *ty = sobj->ty;
PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
PyObject *destroy = data ? data->destroy : 0;
@@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v)
res = ((*meth)(mself, v));
}
Py_XDECREF(res);
- } else {
- const char *name = SWIG_TypePrettyName(ty);
+ }
#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
- printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name);
-#endif
+ else {
+ const char *name = SWIG_TypePrettyName(ty);
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
}
+#endif
}
Py_XDECREF(next);
PyObject_DEL(v);
@@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj)
SWIGRUNTIME int
SWIG_Python_AcquirePtr(PyObject *obj, int own) {
- if (own) {
+ if (own == SWIG_POINTER_OWN) {
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
if (sobj) {
int oldown = sobj->own;
@@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
return SWIG_OK;
} else {
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (own)
+ *own = 0;
while (sobj) {
void *vptr = sobj->ptr;
if (ty) {
@@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
if (!tc) {
sobj = (PySwigObject *)sobj->next;
} else {
- if (ptr) *ptr = SWIG_TypeCast(tc,vptr);
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own);
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
break;
}
}
@@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
}
}
if (sobj) {
- if (own) *own = sobj->own;
+ if (own)
+ *own = *own | sobj->own;
if (flags & SWIG_POINTER_DISOWN) {
sobj->own = 0;
}
@@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
}
if (ty) {
swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
- if (!tc) return SWIG_ERROR;
- *ptr = SWIG_TypeCast(tc,vptr);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ } else {
+ return SWIG_ERROR;
+ }
} else {
*ptr = vptr;
}
@@ -2503,7 +2521,7 @@ static swig_module_info swig_module = {swig_types, 14, 0, 0, 0, 0};
#define SWIG_name "_security"
-#define SWIGVERSION 0x010333
+#define SWIGVERSION 0x010335
#define SWIG_VERSION SWIGVERSION
@@ -3674,7 +3692,7 @@ SWIGRUNTIME void
SWIG_InitializeModule(void *clientdata) {
size_t i;
swig_module_info *module_head, *iter;
- int found;
+ int found, init;
clientdata = clientdata;
@@ -3684,6 +3702,9 @@ SWIG_InitializeModule(void *clientdata) {
swig_module.type_initial = swig_type_initial;
swig_module.cast_initial = swig_cast_initial;
swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
}
/* Try and load any already created modules */
@@ -3712,6 +3733,12 @@ SWIG_InitializeModule(void *clientdata) {
module_head->next = &swig_module;
}
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
/* Now work on filling in swig_module.types */
#ifdef SWIGRUNTIME_DEBUG
printf("SWIG_InitializeModule: size %d\n", swig_module.size);
diff --git a/source4/libcli/security/tests/bindings.py b/source4/libcli/security/tests/bindings.py
index 59a5e69640..82ce7aeba8 100644
--- a/source4/libcli/security/tests/bindings.py
+++ b/source4/libcli/security/tests/bindings.py
@@ -18,7 +18,7 @@
#
import unittest
-import security
+from samba import security
class SecurityTokenTests(unittest.TestCase):
def setUp(self):
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 ab079fefde..00b6305def 100644
--- a/source4/libcli/smb2/config.mk
+++ b/source4/libcli/smb2/config.mk
@@ -1,25 +1,10 @@
[SUBSYSTEM::LIBCLI_SMB2]
-PRIVATE_PROTO_HEADER = smb2_proto.h
-OBJ_FILES = \
- 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
PUBLIC_DEPENDENCIES = LIBCLI_RAW LIBPACKET gensec
+
+LIBCLI_SMB2_OBJ_FILES = $(addprefix $(libclisrcdir)/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 break.o util.o)
+
+$(eval $(call proto_header_template,$(libclisrcdir)/smb2/smb2_proto.h,$(LIBCLI_SMB2_OBJ_FILES:.o=.c)))
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index d68b85ad54..eabfa410ad 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -44,7 +44,7 @@ struct smb2_connect_state {
*/
static void continue_tcon(struct smb2_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private,
+ struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
struct smb2_connect_state *state = talloc_get_type(c->private_data,
struct smb2_connect_state);
@@ -83,7 +83,7 @@ static void continue_session(struct composite_context *creq)
if (composite_nomem(req, c)) return;
req->async.fn = continue_tcon;
- req->async.private = c;
+ req->async.private_data = c;
}
/*
@@ -91,7 +91,7 @@ static void continue_session(struct composite_context *creq)
*/
static void continue_negprot(struct smb2_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private,
+ struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
struct smb2_connect_state *state = talloc_get_type(c->private_data,
struct smb2_connect_state);
@@ -101,6 +101,9 @@ static void continue_negprot(struct smb2_request *req)
c->status = smb2_negprot_recv(req, c, &state->negprot);
if (!composite_is_ok(c)) return;
+ transport->negotiate.system_time = state->negprot.out.system_time;
+ transport->negotiate.server_start_time = state->negprot.out.server_start_time;
+
state->session = smb2_session_init(transport, global_loadparm, state, true);
if (composite_nomem(state->session, c)) return;
@@ -121,7 +124,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,18 +133,19 @@ 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);
if (composite_nomem(req, c)) return;
req->async.fn = continue_negprot;
- req->async.private = c;
+ req->async.private_data = c;
}
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 999c10ab08..b1b8b0ccfa 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;
@@ -87,9 +117,10 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
if (io->in.eas.num_eas != 0) {
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);
+ ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4));
+ ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4);
+ 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/find.c b/source4/libcli/smb2/find.c
index 6b4902a026..8ebfd81bcd 100644
--- a/source4/libcli/smb2/find.c
+++ b/source4/libcli/smb2/find.c
@@ -38,7 +38,7 @@ struct smb2_request *smb2_find_send(struct smb2_tree *tree, struct smb2_find *io
SCVAL(req->out.body, 0x02, io->in.level);
SCVAL(req->out.body, 0x03, io->in.continue_flags);
- SIVAL(req->out.body, 0x04, io->in.unknown);
+ SIVAL(req->out.body, 0x04, io->in.file_index);
smb2_push_handle(req->out.body+0x08, &io->in.file.handle);
status = smb2_push_o16s16_string(&req->out, 0x18, io->in.pattern);
diff --git a/source4/libcli/smb2/flush.c b/source4/libcli/smb2/flush.c
index 116068ed6e..577d1ba1ba 100644
--- a/source4/libcli/smb2/flush.c
+++ b/source4/libcli/smb2/flush.c
@@ -33,8 +33,8 @@ struct smb2_request *smb2_flush_send(struct smb2_tree *tree, struct smb2_flush *
req = smb2_request_init_tree(tree, SMB2_OP_FLUSH, 0x18, false, 0);
if (req == NULL) return NULL;
- SSVAL(req->out.body, 0x02, 0); /* pad? */
- SIVAL(req->out.body, 0x04, io->in.unknown);
+ SSVAL(req->out.body, 0x02, io->in.reserved1);
+ SIVAL(req->out.body, 0x04, io->in.reserved2);
smb2_push_handle(req->out.body+0x08, &io->in.file.handle);
smb2_transport_send(req);
@@ -55,6 +55,8 @@ NTSTATUS smb2_flush_recv(struct smb2_request *req, struct smb2_flush *io)
SMB2_CHECK_PACKET_RECV(req, 0x04, false);
+ io->out.reserved = SVAL(req->in.body, 0x02);
+
return smb2_request_destroy(req);
}
diff --git a/source4/libcli/smb2/lock.c b/source4/libcli/smb2/lock.c
index d71a337d56..62c6e5dba7 100644
--- a/source4/libcli/smb2/lock.c
+++ b/source4/libcli/smb2/lock.c
@@ -29,17 +29,25 @@
struct smb2_request *smb2_lock_send(struct smb2_tree *tree, struct smb2_lock *io)
{
struct smb2_request *req;
+ int i;
- req = smb2_request_init_tree(tree, SMB2_OP_LOCK, 0x30, false, 0);
+ req = smb2_request_init_tree(tree, SMB2_OP_LOCK,
+ 24 + io->in.lock_count*24, false, 0);
if (req == NULL) return NULL;
- SSVAL(req->out.body, 0x02, io->in.unknown1);
- SIVAL(req->out.body, 0x04, io->in.unknown2);
+ /* this is quite bizarre - the spec says we must lie about the length! */
+ SSVAL(req->out.body, 0, 0x30);
+
+ SSVAL(req->out.body, 0x02, io->in.lock_count);
+ SIVAL(req->out.body, 0x04, io->in.reserved);
smb2_push_handle(req->out.body+0x08, &io->in.file.handle);
- SBVAL(req->out.body, 0x18, io->in.offset);
- SBVAL(req->out.body, 0x20, io->in.count);
- SIVAL(req->out.body, 0x24, io->in.unknown5);
- SIVAL(req->out.body, 0x28, io->in.flags);
+
+ for (i=0;i<io->in.lock_count;i++) {
+ SBVAL(req->out.body, 0x18 + i*24, io->in.locks[i].offset);
+ SBVAL(req->out.body, 0x20 + i*24, io->in.locks[i].length);
+ SIVAL(req->out.body, 0x28 + i*24, io->in.locks[i].flags);
+ SIVAL(req->out.body, 0x2C + i*24, io->in.locks[i].reserved);
+ }
smb2_transport_send(req);
@@ -59,7 +67,7 @@ NTSTATUS smb2_lock_recv(struct smb2_request *req, struct smb2_lock *io)
SMB2_CHECK_PACKET_RECV(req, 0x04, false);
- io->out.unknown1 = SVAL(req->in.body, 0x02);
+ io->out.reserved = SVAL(req->in.body, 0x02);
return smb2_request_destroy(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..64d427f889 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -43,6 +43,18 @@ void smb2_setup_bufinfo(struct smb2_request *req)
}
}
+
+/* destroy a request structure */
+static int smb2_request_destructor(struct smb2_request *req)
+{
+ if (req->transport) {
+ /* remove it from the list of pending requests (a null op if
+ its not in the list) */
+ DLIST_REMOVE(req->transport->pending_recv, req);
+ }
+ return 0;
+}
+
/*
initialise a smb2 request
*/
@@ -122,6 +134,8 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
SCVAL(req->out.dynamic, 0, 0);
}
+ talloc_set_destructor(req, smb2_request_destructor);
+
return req;
}
@@ -154,18 +168,13 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req)
_send() call fails completely */
if (!req) return NT_STATUS_UNSUCCESSFUL;
- if (req->transport) {
- /* remove it from the list of pending requests (a null op if
- its not in the list) */
- DLIST_REMOVE(req->transport->pending_recv, req);
- }
-
if (req->state == SMB2_REQUEST_ERROR &&
NT_STATUS_IS_OK(req->status)) {
- req->status = NT_STATUS_INTERNAL_ERROR;
+ status = NT_STATUS_INTERNAL_ERROR;
+ } else {
+ status = req->status;
}
- status = req->status;
talloc_free(req);
return status;
}
@@ -211,10 +220,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 +678,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/session.c b/source4/libcli/smb2/session.c
index 18fe3486a4..29af6652f2 100644
--- a/source4/libcli/smb2/session.c
+++ b/source4/libcli/smb2/session.c
@@ -145,7 +145,7 @@ struct smb2_session_state {
*/
static void session_request_handler(struct smb2_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private,
+ struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
struct smb2_session_state *state = talloc_get_type(c->private_data,
struct smb2_session_state);
@@ -178,7 +178,7 @@ static void session_request_handler(struct smb2_request *req)
}
state->req->async.fn = session_request_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
return;
}
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 726df64090..b55da05e21 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -19,8 +19,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifndef __LIBCLI_SMB2_SMB2_H__
+#define __LIBCLI_SMB2_SMB2_H__
+
#include "libcli/raw/request.h"
+struct smb2_handle;
+
struct smb2_options {
uint32_t timeout;
};
@@ -30,6 +35,8 @@ struct smb2_options {
*/
struct smb2_negotiate {
DATA_BLOB secblob;
+ NTTIME system_time;
+ NTTIME server_start_time;
};
/* this is the context for the smb2 transport layer */
@@ -58,6 +65,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;
};
@@ -154,7 +170,7 @@ struct smb2_request {
*/
struct {
void (*fn)(struct smb2_request *);
- void *private;
+ void *private_data;
} async;
};
@@ -271,3 +287,5 @@ struct smb2_request {
return NT_STATUS_INVALID_PARAMETER; \
} \
} while (0)
+
+#endif
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/smb2/util.c b/source4/libcli/smb2/util.c
new file mode 100644
index 0000000000..9eb344e83f
--- /dev/null
+++ b/source4/libcli/smb2/util.c
@@ -0,0 +1,200 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ SMB2 client utility functions
+
+ Copyright (C) Andrew Tridgell 2005
+
+ 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/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "libcli/smb_composite/smb_composite.h"
+
+/*
+ simple close wrapper with SMB2
+*/
+NTSTATUS smb2_util_close(struct smb2_tree *tree, struct smb2_handle h)
+{
+ struct smb2_close c;
+
+ ZERO_STRUCT(c);
+ c.in.file.handle = h;
+
+ return smb2_close(tree, &c);
+}
+
+/*
+ unlink a file with SMB2
+*/
+NTSTATUS smb2_util_unlink(struct smb2_tree *tree, const char *fname)
+{
+ union smb_unlink io;
+
+ ZERO_STRUCT(io);
+ io.unlink.in.pattern = fname;
+
+ return smb2_composite_unlink(tree, &io);
+}
+
+
+/*
+ rmdir with SMB2
+*/
+NTSTATUS smb2_util_rmdir(struct smb2_tree *tree, const char *dname)
+{
+ struct smb_rmdir io;
+
+ ZERO_STRUCT(io);
+ io.in.path = dname;
+
+ return smb2_composite_rmdir(tree, &io);
+}
+
+
+/*
+ mkdir with SMB2
+*/
+NTSTATUS smb2_util_mkdir(struct smb2_tree *tree, const char *dname)
+{
+ union smb_mkdir io;
+
+ ZERO_STRUCT(io);
+ io.mkdir.level = RAW_MKDIR_MKDIR;
+ io.mkdir.in.path = dname;
+
+ return smb2_composite_mkdir(tree, &io);
+}
+
+
+/*
+ set file attribute with SMB2
+*/
+NTSTATUS smb2_util_setatr(struct smb2_tree *tree, const char *name, uint32_t attrib)
+{
+ union smb_setfileinfo io;
+
+ ZERO_STRUCT(io);
+ io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION;
+ io.basic_info.in.file.path = name;
+ io.basic_info.in.attrib = attrib;
+
+ return smb2_composite_setpathinfo(tree, &io);
+}
+
+
+
+
+/*
+ recursively descend a tree deleting all files
+ returns the number of files deleted, or -1 on error
+*/
+int smb2_deltree(struct smb2_tree *tree, const char *dname)
+{
+ NTSTATUS status;
+ uint32_t total_deleted = 0;
+ uint_t count, i;
+ union smb_search_data *list;
+ TALLOC_CTX *tmp_ctx = talloc_new(tree);
+ struct smb2_find f;
+ struct smb2_create create_parm;
+
+ /* it might be a file */
+ status = smb2_util_unlink(tree, dname);
+ if (NT_STATUS_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return 1;
+ }
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE)) {
+ talloc_free(tmp_ctx);
+ return 0;
+ }
+
+ ZERO_STRUCT(create_parm);
+ create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+ create_parm.in.share_access =
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create_parm.in.fname = dname;
+
+ status = smb2_create(tree, tmp_ctx, &create_parm);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(2,("Failed to open %s - %s\n", dname, nt_errstr(status)));
+ talloc_free(tmp_ctx);
+ return -1;
+ }
+
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = create_parm.out.file.handle;
+ f.in.max_response_size = 0x10000;
+ f.in.level = SMB2_FIND_NAME_INFO;
+ f.in.pattern = "*";
+
+ status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(2,("Failed to list %s - %s\n",
+ dname, nt_errstr(status)));
+ smb2_util_close(tree, create_parm.out.file.handle);
+ talloc_free(tmp_ctx);
+ return -1;
+ }
+
+ for (i=0;i<count;i++) {
+ char *name;
+ if (strcmp(".", list[i].name_info.name.s) == 0 ||
+ strcmp("..", list[i].name_info.name.s) == 0) {
+ continue;
+ }
+ name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
+ status = smb2_util_unlink(tree, name);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+ /* it could be read-only */
+ status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
+ status = smb2_util_unlink(tree, name);
+ }
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ int ret;
+ ret = smb2_deltree(tree, name);
+ if (ret > 0) total_deleted += ret;
+ }
+ talloc_free(name);
+ if (NT_STATUS_IS_OK(status)) {
+ total_deleted++;
+ }
+ }
+
+ smb2_util_close(tree, create_parm.out.file.handle);
+
+ status = smb2_util_rmdir(tree, dname);
+ if (NT_STATUS_IS_ERR(status)) {
+ DEBUG(2,("Failed to delete %s - %s\n",
+ dname, nt_errstr(status)));
+ talloc_free(tmp_ctx);
+ return -1;
+ }
+
+ talloc_free(tmp_ctx);
+
+ return total_deleted;
+}
diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c
index c44c62f868..e56339f96b 100644
--- a/source4/libcli/smb_composite/connect.c
+++ b/source4/libcli/smb_composite/connect.c
@@ -38,7 +38,9 @@ enum connect_stage {CONNECT_RESOLVE,
CONNECT_NEGPROT,
CONNECT_SESSION_SETUP,
CONNECT_SESSION_SETUP_ANON,
- CONNECT_TCON};
+ CONNECT_TCON,
+ CONNECT_DONE
+};
struct connect_state {
enum connect_stage stage;
@@ -57,25 +59,6 @@ static void request_handler(struct smbcli_request *);
static void composite_handler(struct composite_context *);
/*
- setup a negprot send
-*/
-static NTSTATUS connect_send_negprot(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
-
- state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- state->req->async.fn = request_handler;
- state->req->async.private = c;
- state->stage = CONNECT_NEGPROT;
-
- return NT_STATUS_OK;
-}
-
-
-/*
a tree connect request has completed
*/
static NTSTATUS connect_tcon(struct composite_context *c,
@@ -97,8 +80,7 @@ static NTSTATUS connect_tcon(struct composite_context *c,
state->io_tcon->tconx.out.fs_type);
}
- /* all done! */
- c->state = COMPOSITE_STATE_DONE;
+ state->stage = CONNECT_DONE;
return NT_STATUS_OK;
}
@@ -121,9 +103,6 @@ static NTSTATUS connect_session_setup_anon(struct composite_context *c,
state->session->vuid = state->io_setup->out.vuid;
/* setup for a tconx */
- io->out.tree = smbcli_tree_init(state->session, state, true);
- NT_STATUS_HAVE_NO_MEMORY(io->out.tree);
-
state->io_tcon = talloc(c, union smb_tcon);
NT_STATUS_HAVE_NO_MEMORY(state->io_tcon);
@@ -203,9 +182,12 @@ static NTSTATUS connect_session_setup(struct composite_context *c,
state->session->vuid = state->io_setup->out.vuid;
- /* setup for a tconx */
- io->out.tree = smbcli_tree_init(state->session, state, true);
- NT_STATUS_HAVE_NO_MEMORY(io->out.tree);
+ /* If we don't have a remote share name then this indicates that
+ * we don't want to do a tree connect */
+ if (!io->in.service) {
+ state->stage = CONNECT_DONE;
+ return NT_STATUS_OK;
+ }
state->io_tcon = talloc(c, union smb_tcon);
NT_STATUS_HAVE_NO_MEMORY(state->io_tcon);
@@ -254,6 +236,18 @@ static NTSTATUS connect_negprot(struct composite_context *c,
/* next step is a session setup */
state->session = smbcli_session_init(state->transport, state, true);
NT_STATUS_HAVE_NO_MEMORY(state->session);
+
+ /* setup for a tconx (or at least have the structure ready to
+ * return, if we won't go that far) */
+ io->out.tree = smbcli_tree_init(state->session, state, true);
+ NT_STATUS_HAVE_NO_MEMORY(io->out.tree);
+
+ /* If we don't have any credentials then this indicates that
+ * we don't want to do a session setup */
+ if (!io->in.credentials) {
+ state->stage = CONNECT_DONE;
+ return NT_STATUS_OK;
+ }
state->io_setup = talloc(c, struct smb_composite_sesssetup);
NT_STATUS_HAVE_NO_MEMORY(state->io_setup);
@@ -272,11 +266,30 @@ static NTSTATUS connect_negprot(struct composite_context *c,
state->creq->async.fn = composite_handler;
state->creq->async.private_data = c;
+
state->stage = CONNECT_SESSION_SETUP;
return NT_STATUS_OK;
}
+/*
+ setup a negprot send
+*/
+static NTSTATUS connect_send_negprot(struct composite_context *c,
+ struct smb_composite_connect *io)
+{
+ struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
+
+ state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol);
+ NT_STATUS_HAVE_NO_MEMORY(state->req);
+
+ state->req->async.fn = request_handler;
+ state->req->async.private = c;
+ state->stage = CONNECT_NEGPROT;
+
+ return NT_STATUS_OK;
+}
+
/*
a session request operation has completed
@@ -405,13 +418,11 @@ static void state_handler(struct composite_context *c)
break;
}
- if (!NT_STATUS_IS_OK(c->status)) {
- c->state = COMPOSITE_STATE_ERROR;
- }
-
- if (c->state >= COMPOSITE_STATE_DONE &&
- c->async.fn) {
- c->async.fn(c);
+ if (state->stage == CONNECT_DONE) {
+ /* all done! */
+ composite_done(c);
+ } else {
+ composite_is_ok(c);
}
}
@@ -451,17 +462,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/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c
index 1427fe525b..11ac37e257 100644
--- a/source4/libcli/smb_composite/sesssetup.c
+++ b/source4/libcli/smb_composite/sesssetup.c
@@ -224,7 +224,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c,
{
NTSTATUS nt_status;
struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);
- const char *password = cli_credentials_get_password(io->in.credentials);
DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm));
DATA_BLOB session_key;
int flags = CLI_CRED_NTLM_AUTH;
@@ -266,6 +265,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c,
data_blob_free(&session_key);
} else if (session->options.plaintext_auth) {
+ const char *password = cli_credentials_get_password(io->in.credentials);
state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password));
state->setup.nt1.in.password2 = data_blob(NULL, 0);
} else {
diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c
new file mode 100644
index 0000000000..6e005e03c0
--- /dev/null
+++ b/source4/libcli/smb_composite/smb2.c
@@ -0,0 +1,371 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 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/>.
+*/
+/*
+ a composite API for making SMB-like calls using SMB2. This is useful
+ as SMB2 often requires more than one requests where a single SMB
+ request would do. In converting code that uses SMB to use SMB2,
+ these routines make life a lot easier
+*/
+
+
+#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/composite/composite.h"
+#include "libcli/smb_composite/smb_composite.h"
+#include "param/param.h"
+#include "libcli/smb2/smb2_calls.h"
+
+/*
+ continue after a SMB2 close
+ */
+static void continue_close(struct smb2_request *req)
+{
+ struct composite_context *ctx = talloc_get_type(req->async.private_data,
+ struct composite_context);
+ NTSTATUS status;
+ struct smb2_close close_parm;
+
+ status = smb2_close_recv(req, &close_parm);
+ composite_error(ctx, status);
+}
+
+/*
+ continue after the create in a composite unlink
+ */
+static void continue_unlink(struct smb2_request *req)
+{
+ struct composite_context *ctx = talloc_get_type(req->async.private_data,
+ struct composite_context);
+ struct smb2_tree *tree = req->tree;
+ struct smb2_create create_parm;
+ struct smb2_close close_parm;
+ NTSTATUS status;
+
+ status = smb2_create_recv(req, ctx, &create_parm);
+ if (!NT_STATUS_IS_OK(status)) {
+ composite_error(ctx, status);
+ return;
+ }
+
+ ZERO_STRUCT(close_parm);
+ close_parm.in.file.handle = create_parm.out.file.handle;
+
+ req = smb2_close_send(tree, &close_parm);
+ composite_continue_smb2(ctx, req, continue_close, ctx);
+}
+
+/*
+ composite SMB2 unlink call
+*/
+struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree,
+ union smb_unlink *io)
+{
+ struct composite_context *ctx;
+ struct smb2_create create_parm;
+ struct smb2_request *req;
+
+ ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+ if (ctx == NULL) return NULL;
+
+ /* check for wildcards - we could support these with a
+ search, but for now they aren't necessary */
+ if (strpbrk(io->unlink.in.pattern, "*?<>") != NULL) {
+ composite_error(ctx, NT_STATUS_NOT_SUPPORTED);
+ return ctx;
+ }
+
+ ZERO_STRUCT(create_parm);
+ create_parm.in.desired_access = SEC_STD_DELETE;
+ create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create_parm.in.share_access =
+ NTCREATEX_SHARE_ACCESS_DELETE|
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ create_parm.in.create_options =
+ NTCREATEX_OPTIONS_DELETE_ON_CLOSE |
+ NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
+ create_parm.in.fname = io->unlink.in.pattern;
+ if (create_parm.in.fname[0] == '\\') {
+ create_parm.in.fname++;
+ }
+
+ req = smb2_create_send(tree, &create_parm);
+
+ composite_continue_smb2(ctx, req, continue_unlink, ctx);
+ return ctx;
+}
+
+
+/*
+ composite unlink call - sync interface
+*/
+NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io)
+{
+ struct composite_context *c = smb2_composite_unlink_send(tree, io);
+ return composite_wait_free(c);
+}
+
+
+
+
+/*
+ continue after the create in a composite mkdir
+ */
+static void continue_mkdir(struct smb2_request *req)
+{
+ struct composite_context *ctx = talloc_get_type(req->async.private_data,
+ struct composite_context);
+ struct smb2_tree *tree = req->tree;
+ struct smb2_create create_parm;
+ struct smb2_close close_parm;
+ NTSTATUS status;
+
+ status = smb2_create_recv(req, ctx, &create_parm);
+ if (!NT_STATUS_IS_OK(status)) {
+ composite_error(ctx, status);
+ return;
+ }
+
+ ZERO_STRUCT(close_parm);
+ close_parm.in.file.handle = create_parm.out.file.handle;
+
+ req = smb2_close_send(tree, &close_parm);
+ composite_continue_smb2(ctx, req, continue_close, ctx);
+}
+
+/*
+ composite SMB2 mkdir call
+*/
+struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree,
+ union smb_mkdir *io)
+{
+ struct composite_context *ctx;
+ struct smb2_create create_parm;
+ struct smb2_request *req;
+
+ ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+ if (ctx == NULL) return NULL;
+
+ ZERO_STRUCT(create_parm);
+
+ create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+ create_parm.in.share_access =
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create_parm.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create_parm.in.create_disposition = NTCREATEX_DISP_CREATE;
+ create_parm.in.fname = io->mkdir.in.path;
+ if (create_parm.in.fname[0] == '\\') {
+ create_parm.in.fname++;
+ }
+
+ req = smb2_create_send(tree, &create_parm);
+
+ composite_continue_smb2(ctx, req, continue_mkdir, ctx);
+
+ return ctx;
+}
+
+
+/*
+ composite mkdir call - sync interface
+*/
+NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io)
+{
+ struct composite_context *c = smb2_composite_mkdir_send(tree, io);
+ return composite_wait_free(c);
+}
+
+
+
+/*
+ continue after the create in a composite rmdir
+ */
+static void continue_rmdir(struct smb2_request *req)
+{
+ struct composite_context *ctx = talloc_get_type(req->async.private_data,
+ struct composite_context);
+ struct smb2_tree *tree = req->tree;
+ struct smb2_create create_parm;
+ struct smb2_close close_parm;
+ NTSTATUS status;
+
+ status = smb2_create_recv(req, ctx, &create_parm);
+ if (!NT_STATUS_IS_OK(status)) {
+ composite_error(ctx, status);
+ return;
+ }
+
+ ZERO_STRUCT(close_parm);
+ close_parm.in.file.handle = create_parm.out.file.handle;
+
+ req = smb2_close_send(tree, &close_parm);
+ composite_continue_smb2(ctx, req, continue_close, ctx);
+}
+
+/*
+ composite SMB2 rmdir call
+*/
+struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree,
+ struct smb_rmdir *io)
+{
+ struct composite_context *ctx;
+ struct smb2_create create_parm;
+ struct smb2_request *req;
+
+ ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+ if (ctx == NULL) return NULL;
+
+ ZERO_STRUCT(create_parm);
+ create_parm.in.desired_access = SEC_STD_DELETE;
+ create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create_parm.in.share_access =
+ NTCREATEX_SHARE_ACCESS_DELETE|
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ create_parm.in.create_options =
+ NTCREATEX_OPTIONS_DIRECTORY |
+ NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
+ create_parm.in.fname = io->in.path;
+ if (create_parm.in.fname[0] == '\\') {
+ create_parm.in.fname++;
+ }
+
+ req = smb2_create_send(tree, &create_parm);
+
+ composite_continue_smb2(ctx, req, continue_rmdir, ctx);
+ return ctx;
+}
+
+
+/*
+ composite rmdir call - sync interface
+*/
+NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io)
+{
+ struct composite_context *c = smb2_composite_rmdir_send(tree, io);
+ return composite_wait_free(c);
+}
+
+
+/*
+ continue after the setfileinfo in a composite setpathinfo
+ */
+static void continue_setpathinfo_close(struct smb2_request *req)
+{
+ struct composite_context *ctx = talloc_get_type(req->async.private_data,
+ struct composite_context);
+ struct smb2_tree *tree = req->tree;
+ struct smb2_close close_parm;
+ NTSTATUS status;
+ union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data,
+ union smb_setfileinfo);
+
+ status = smb2_setinfo_recv(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ composite_error(ctx, status);
+ return;
+ }
+
+ ZERO_STRUCT(close_parm);
+ close_parm.in.file.handle = io2->generic.in.file.handle;
+
+ req = smb2_close_send(tree, &close_parm);
+ composite_continue_smb2(ctx, req, continue_close, ctx);
+}
+
+
+/*
+ continue after the create in a composite setpathinfo
+ */
+static void continue_setpathinfo(struct smb2_request *req)
+{
+ struct composite_context *ctx = talloc_get_type(req->async.private_data,
+ struct composite_context);
+ struct smb2_tree *tree = req->tree;
+ struct smb2_create create_parm;
+ NTSTATUS status;
+ union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data,
+ union smb_setfileinfo);
+
+ status = smb2_create_recv(req, ctx, &create_parm);
+ if (!NT_STATUS_IS_OK(status)) {
+ composite_error(ctx, status);
+ return;
+ }
+
+ io2->generic.in.file.handle = create_parm.out.file.handle;
+
+ req = smb2_setinfo_file_send(tree, io2);
+ composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx);
+}
+
+
+/*
+ composite SMB2 setpathinfo call
+*/
+struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree,
+ union smb_setfileinfo *io)
+{
+ struct composite_context *ctx;
+ struct smb2_create create_parm;
+ struct smb2_request *req;
+ union smb_setfileinfo *io2;
+
+ ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+ if (ctx == NULL) return NULL;
+
+ ZERO_STRUCT(create_parm);
+ create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+ create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create_parm.in.share_access =
+ NTCREATEX_SHARE_ACCESS_DELETE|
+ NTCREATEX_SHARE_ACCESS_READ|
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ create_parm.in.create_options = 0;
+ create_parm.in.fname = io->generic.in.file.path;
+ if (create_parm.in.fname[0] == '\\') {
+ create_parm.in.fname++;
+ }
+
+ req = smb2_create_send(tree, &create_parm);
+
+ io2 = talloc(ctx, union smb_setfileinfo);
+ if (composite_nomem(io2, ctx)) {
+ return ctx;
+ }
+ *io2 = *io;
+
+ ctx->private_data = io2;
+
+ composite_continue_smb2(ctx, req, continue_setpathinfo, ctx);
+ return ctx;
+}
+
+
+/*
+ composite setpathinfo call
+ */
+NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io)
+{
+ struct composite_context *c = smb2_composite_setpathinfo_send(tree, io);
+ return composite_wait_free(c);
+}
diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h
index e7e131869c..7f4b9d73e4 100644
--- a/source4/libcli/smb_composite/smb_composite.h
+++ b/source4/libcli/smb_composite/smb_composite.h
@@ -29,6 +29,7 @@
#include "libcli/raw/signing.h"
#include "libcli/raw/libcliraw.h"
+#include "libcli/smb2/smb2.h"
/*
@@ -83,8 +84,8 @@ struct smb_composite_savefile {
- socket establishment
- session request
- negprot
- - session setup
- - tree connect
+ - session setup (if credentials are not NULL)
+ - tree connect (if service is not NULL)
*/
struct smb_composite_connect {
struct {
diff --git a/source4/libcli/swig/libcli_nbt.py b/source4/libcli/swig/libcli_nbt.py
index b49e240bc2..a26aa6092e 100644
--- a/source4/libcli/swig/libcli_nbt.py
+++ b/source4/libcli/swig/libcli_nbt.py
@@ -1,5 +1,5 @@
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.33
+# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
diff --git a/source4/libcli/swig/libcli_nbt_wrap.c b/source4/libcli/swig/libcli_nbt_wrap.c
index e0bdb27cfc..2deec98cb5 100644
--- a/source4/libcli/swig/libcli_nbt_wrap.c
+++ b/source4/libcli/swig/libcli_nbt_wrap.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3.33
+ * Version 1.3.35
*
* This file is not intended to be easily readable and contains a number of
* coding conventions designed to improve portability and efficiency. Do not make
@@ -126,7 +126,7 @@
/* This should only be incremented when either the layout of swig_type_info changes,
or for whatever reason, the runtime changes incompatibly */
-#define SWIG_RUNTIME_VERSION "3"
+#define SWIG_RUNTIME_VERSION "4"
/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
#ifdef SWIG_TYPE_TABLE
@@ -161,6 +161,7 @@
/* Flags for pointer conversions */
#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
/* Flags for new pointer objects */
#define SWIG_POINTER_OWN 0x1
@@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) {
extern "C" {
#endif
-typedef void *(*swig_converter_func)(void *);
+typedef void *(*swig_converter_func)(void *, int *);
typedef struct swig_type_info *(*swig_dycast_func)(void **);
-/* Structure to store inforomation on one type */
+/* Structure to store information on one type */
typedef struct swig_type_info {
const char *name; /* mangled name of this type */
const char *str; /* human readable name of this type */
@@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
Cast a pointer up an inheritance hierarchy
*/
SWIGRUNTIMEINLINE void *
-SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
- return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
}
/*
@@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg)
Py_DECREF(old_str);
Py_DECREF(value);
} else {
- PyErr_Format(PyExc_RuntimeError, mesg);
+ PyErr_SetString(PyExc_RuntimeError, mesg);
}
}
@@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v)
{
PySwigObject *sobj = (PySwigObject *) v;
PyObject *next = sobj->next;
- if (sobj->own) {
+ if (sobj->own == SWIG_POINTER_OWN) {
swig_type_info *ty = sobj->ty;
PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
PyObject *destroy = data ? data->destroy : 0;
@@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v)
res = ((*meth)(mself, v));
}
Py_XDECREF(res);
- } else {
- const char *name = SWIG_TypePrettyName(ty);
+ }
#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
- printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name);
-#endif
+ else {
+ const char *name = SWIG_TypePrettyName(ty);
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
}
+#endif
}
Py_XDECREF(next);
PyObject_DEL(v);
@@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj)
SWIGRUNTIME int
SWIG_Python_AcquirePtr(PyObject *obj, int own) {
- if (own) {
+ if (own == SWIG_POINTER_OWN) {
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
if (sobj) {
int oldown = sobj->own;
@@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
return SWIG_OK;
} else {
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (own)
+ *own = 0;
while (sobj) {
void *vptr = sobj->ptr;
if (ty) {
@@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
if (!tc) {
sobj = (PySwigObject *)sobj->next;
} else {
- if (ptr) *ptr = SWIG_TypeCast(tc,vptr);
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own);
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
break;
}
}
@@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
}
}
if (sobj) {
- if (own) *own = sobj->own;
+ if (own)
+ *own = *own | sobj->own;
if (flags & SWIG_POINTER_DISOWN) {
sobj->own = 0;
}
@@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
}
if (ty) {
swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
- if (!tc) return SWIG_ERROR;
- *ptr = SWIG_TypeCast(tc,vptr);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ } else {
+ return SWIG_ERROR;
+ }
} else {
*ptr = vptr;
}
@@ -2507,7 +2525,7 @@ static swig_module_info swig_module = {swig_types, 18, 0, 0, 0, 0};
#define SWIG_name "_libcli_nbt"
-#define SWIGVERSION 0x010333
+#define SWIGVERSION 0x010335
#define SWIG_VERSION SWIGVERSION
@@ -3134,7 +3152,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name(PyObject *SWIGUNUSEDPARM(self), PyObject
struct nbt_name *result = 0 ;
if (!SWIG_Python_UnpackTuple(args,"new_nbt_name",0,0,0)) SWIG_fail;
- result = (struct nbt_name *)(struct nbt_name *) calloc(1, sizeof(struct nbt_name));
+ result = (struct nbt_name *)calloc(1, sizeof(struct nbt_name));
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name, SWIG_POINTER_NEW | 0 );
return resultobj;
fail:
@@ -3227,7 +3245,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), Py
struct nbt_name_query *result = 0 ;
if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query",0,0,0)) SWIG_fail;
- result = (struct nbt_name_query *)(struct nbt_name_query *) calloc(1, sizeof(struct nbt_name_query));
+ result = (struct nbt_name_query *)calloc(1, sizeof(struct nbt_name_query));
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query, SWIG_POINTER_NEW | 0 );
return resultobj;
fail:
@@ -3493,7 +3511,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query_out(PyObject *SWIGUNUSEDPARM(self)
nbt_name_query_out *result = 0 ;
if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_out",0,0,0)) SWIG_fail;
- result = (nbt_name_query_out *)(nbt_name_query_out *) calloc(1, sizeof(nbt_name_query_out));
+ result = (nbt_name_query_out *)calloc(1, sizeof(nbt_name_query_out));
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_out, SWIG_POINTER_NEW | 0 );
return resultobj;
fail:
@@ -3865,7 +3883,7 @@ SWIGINTERN PyObject *_wrap_new_nbt_name_query_in(PyObject *SWIGUNUSEDPARM(self),
nbt_name_query_in *result = 0 ;
if (!SWIG_Python_UnpackTuple(args,"new_nbt_name_query_in",0,0,0)) SWIG_fail;
- result = (nbt_name_query_in *)(nbt_name_query_in *) calloc(1, sizeof(nbt_name_query_in));
+ result = (nbt_name_query_in *)calloc(1, sizeof(nbt_name_query_in));
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_nbt_name_query_in, SWIG_POINTER_NEW | 0 );
return resultobj;
fail:
@@ -4280,7 +4298,7 @@ SWIGRUNTIME void
SWIG_InitializeModule(void *clientdata) {
size_t i;
swig_module_info *module_head, *iter;
- int found;
+ int found, init;
clientdata = clientdata;
@@ -4290,6 +4308,9 @@ SWIG_InitializeModule(void *clientdata) {
swig_module.type_initial = swig_type_initial;
swig_module.cast_initial = swig_cast_initial;
swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
}
/* Try and load any already created modules */
@@ -4318,6 +4339,12 @@ SWIG_InitializeModule(void *clientdata) {
module_head->next = &swig_module;
}
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
/* Now work on filling in swig_module.types */
#ifdef SWIGRUNTIME_DEBUG
printf("SWIG_InitializeModule: size %d\n", swig_module.size);
diff --git a/source4/libcli/swig/libcli_smb.py b/source4/libcli/swig/libcli_smb.py
index 80c4040237..6e4fe036c7 100644
--- a/source4/libcli/swig/libcli_smb.py
+++ b/source4/libcli/swig/libcli_smb.py
@@ -1,5 +1,5 @@
# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.33
+# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
diff --git a/source4/libcli/swig/libcli_smb_wrap.c b/source4/libcli/swig/libcli_smb_wrap.c
index 8b71f2c3be..de8e6ba1e4 100644
--- a/source4/libcli/swig/libcli_smb_wrap.c
+++ b/source4/libcli/swig/libcli_smb_wrap.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3.33
+ * Version 1.3.35
*
* This file is not intended to be easily readable and contains a number of
* coding conventions designed to improve portability and efficiency. Do not make
@@ -126,7 +126,7 @@
/* This should only be incremented when either the layout of swig_type_info changes,
or for whatever reason, the runtime changes incompatibly */
-#define SWIG_RUNTIME_VERSION "3"
+#define SWIG_RUNTIME_VERSION "4"
/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
#ifdef SWIG_TYPE_TABLE
@@ -161,6 +161,7 @@
/* Flags for pointer conversions */
#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
/* Flags for new pointer objects */
#define SWIG_POINTER_OWN 0x1
@@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) {
extern "C" {
#endif
-typedef void *(*swig_converter_func)(void *);
+typedef void *(*swig_converter_func)(void *, int *);
typedef struct swig_type_info *(*swig_dycast_func)(void **);
-/* Structure to store inforomation on one type */
+/* Structure to store information on one type */
typedef struct swig_type_info {
const char *name; /* mangled name of this type */
const char *str; /* human readable name of this type */
@@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
Cast a pointer up an inheritance hierarchy
*/
SWIGRUNTIMEINLINE void *
-SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
- return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
}
/*
@@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg)
Py_DECREF(old_str);
Py_DECREF(value);
} else {
- PyErr_Format(PyExc_RuntimeError, mesg);
+ PyErr_SetString(PyExc_RuntimeError, mesg);
}
}
@@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v)
{
PySwigObject *sobj = (PySwigObject *) v;
PyObject *next = sobj->next;
- if (sobj->own) {
+ if (sobj->own == SWIG_POINTER_OWN) {
swig_type_info *ty = sobj->ty;
PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
PyObject *destroy = data ? data->destroy : 0;
@@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v)
res = ((*meth)(mself, v));
}
Py_XDECREF(res);
- } else {
- const char *name = SWIG_TypePrettyName(ty);
+ }
#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
- printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name);
-#endif
+ else {
+ const char *name = SWIG_TypePrettyName(ty);
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
}
+#endif
}
Py_XDECREF(next);
PyObject_DEL(v);
@@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj)
SWIGRUNTIME int
SWIG_Python_AcquirePtr(PyObject *obj, int own) {
- if (own) {
+ if (own == SWIG_POINTER_OWN) {
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
if (sobj) {
int oldown = sobj->own;
@@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
return SWIG_OK;
} else {
PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (own)
+ *own = 0;
while (sobj) {
void *vptr = sobj->ptr;
if (ty) {
@@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
if (!tc) {
sobj = (PySwigObject *)sobj->next;
} else {
- if (ptr) *ptr = SWIG_TypeCast(tc,vptr);
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own);
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
break;
}
}
@@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
}
}
if (sobj) {
- if (own) *own = sobj->own;
+ if (own)
+ *own = *own | sobj->own;
if (flags & SWIG_POINTER_DISOWN) {
sobj->own = 0;
}
@@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
}
if (ty) {
swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
- if (!tc) return SWIG_ERROR;
- *ptr = SWIG_TypeCast(tc,vptr);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ } else {
+ return SWIG_ERROR;
+ }
} else {
*ptr = vptr;
}
@@ -2495,7 +2513,7 @@ static swig_module_info swig_module = {swig_types, 6, 0, 0, 0, 0};
#define SWIG_name "_libcli_smb"
-#define SWIGVERSION 0x010333
+#define SWIGVERSION 0x010335
#define SWIG_VERSION SWIGVERSION
@@ -2769,7 +2787,7 @@ SWIGRUNTIME void
SWIG_InitializeModule(void *clientdata) {
size_t i;
swig_module_info *module_head, *iter;
- int found;
+ int found, init;
clientdata = clientdata;
@@ -2779,6 +2797,9 @@ SWIG_InitializeModule(void *clientdata) {
swig_module.type_initial = swig_type_initial;
swig_module.cast_initial = swig_cast_initial;
swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
}
/* Try and load any already created modules */
@@ -2807,6 +2828,12 @@ SWIG_InitializeModule(void *clientdata) {
module_head->next = &swig_module;
}
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
/* Now work on filling in swig_module.types */
#ifdef SWIGRUNTIME_DEBUG
printf("SWIG_InitializeModule: size %d\n", swig_module.size);
diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk
index 9384a172ff..00df5dbb22 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 = $(libclisrcdir)/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;