diff options
Diffstat (limited to 'source4/libcli')
57 files changed, 1091 insertions, 3902 deletions
diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c index a6cb17c12e..3c77b0836d 100644 --- a/source4/libcli/auth/credentials.c +++ b/source4/libcli/auth/credentials.c @@ -23,7 +23,7 @@ #include "includes.h" #include "system/time.h" #include "auth/auth.h" -#include "lib/crypto/crypto.h" +#include "../lib/crypto/crypto.h" #include "libcli/auth/libcli_auth.h" /* diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index 7de9627302..3af7e45002 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -25,7 +25,7 @@ #include "system/time.h" #include "auth/ntlmssp/ntlmssp.h" #include "auth/ntlmssp/msrpc_parse.h" -#include "lib/crypto/crypto.h" +#include "../lib/crypto/crypto.h" #include "libcli/auth/libcli_auth.h" #include "pstring.h" #include "param/param.h" @@ -497,10 +497,10 @@ bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag returned password including termination. ************************************************************/ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32_t *new_pw_len, - int string_flags) + int new_pwrd_size, int string_flags) { int byte_len=0; + ssize_t converted_pw_len; /* the incoming buffer can be any alignment. */ string_flags |= STR_NOALIGN; @@ -526,13 +526,17 @@ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, } /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + converted_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, string_flags); + if (converted_pw_len == -1) { + return false; + } + #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len); - DEBUG(100,("multibyte len:%d\n", *new_pw_len)); + dump_data(100, (const uint8_t *)new_pwrd, converted_pw_len); + DEBUG(100,("multibyte len:%d\n", converted_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 7c2daf0ca2..c1a3b6b63e 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -20,7 +20,7 @@ */ #include "lib/util/asn1.h" -#include "libcli/netlogon.h" +#include "../libcli/netlogon.h" struct ldap_message; diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index c20a7fd935..e42b04cdc5 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -69,12 +69,14 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) /* wrapper around smb_raw_sesssetup() */ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, struct cli_credentials *credentials, - const char *workgroup) + const char *workgroup, + struct smbcli_session_options options) { struct smb_composite_sesssetup setup; NTSTATUS status; - cli->session = smbcli_session_init(cli->transport, cli, true); + cli->session = smbcli_session_init(cli->transport, cli, true, + options); if (!cli->session) return NT_STATUS_UNSUCCESSFUL; setup.in.sesskey = cli->transport->negotiate.sesskey; @@ -144,7 +146,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, struct event_context *ev, - struct smbcli_options *options) + struct smbcli_options *options, + struct smbcli_session_options *session_options) { struct smbcli_tree *tree; NTSTATUS status; @@ -155,7 +158,8 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, &tree, host, ports, sharename, devtype, credentials, resolve_ctx, ev, - options); + options, + session_options); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 2c306e501e..28563d918e 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -84,12 +84,14 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) { char *mask; struct delete_state dstate; + NTSTATUS status; dstate.tree = tree; dstate.total_deleted = 0; dstate.failed = false; /* it might be a file */ + status = smbcli_unlink(tree, dname); if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { return 1; } @@ -98,6 +100,13 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) { return 0; } + if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { + /* it could be read-only */ + status = smbcli_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL, 0); + if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { + return 1; + } + } asprintf(&mask, "%s\\*", dname); smbcli_unlink(dstate.tree, mask); @@ -105,7 +114,14 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, delete_fn, &dstate); free(mask); - if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate.tree, dname))) { + + status = smbcli_rmdir(dstate.tree, dname); + if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { + /* it could be read-only */ + status = smbcli_setatr(dstate.tree, dname, FILE_ATTRIBUTE_NORMAL, 0); + status = smbcli_rmdir(dstate.tree, dname); + } + if (NT_STATUS_IS_ERR(status)) { DEBUG(2,("Failed to delete %s - %s\n", dname, smbcli_errstr(dstate.tree))); return -1; diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c index 3e3f224f47..104397fa48 100644 --- a/source4/libcli/composite/composite.c +++ b/source4/libcli/composite/composite.c @@ -28,7 +28,7 @@ #include "libcli/composite/composite.h" #include "lib/messaging/irpc.h" #include "librpc/rpc/dcerpc.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" /* create a new composite_context structure @@ -214,5 +214,5 @@ _PUBLIC_ void composite_continue_nbt(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; } diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 262a2cfa22..8d9a1f5fa8 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -40,52 +40,52 @@ $(eval $(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBC [SUBSYSTEM::NDR_NBT_BUF] -NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o +NDR_NBT_BUF_OBJ_FILES = $(libclinbtsrcdir)/nbtname.o -$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,$(libclinbtsrcdir)/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c))) [SUBSYSTEM::LIBCLI_NBT] PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \ NDR_SECURITY samba-socket LIBSAMBA-UTIL -LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ +LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclinbtsrcdir)/, \ 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))) +[BINARY::nmblookup] +INSTALLDIR = BINDIR +PRIVATE_DEPENDENCIES = \ + LIBSAMBA-HOSTCONFIG \ + LIBSAMBA-UTIL \ + LIBCLI_NBT \ + LIBPOPT \ + POPT_SAMBA \ + LIBNETIF \ + LIBCLI_RESOLVE + +nmblookup_OBJ_FILES = $(libclinbtsrcdir)/tools/nmblookup.o +MANPAGES += $(libclinbtsrcdir)/man/nmblookup.1 [SUBSYSTEM::LIBCLI_NDR_NETLOGON] PUBLIC_DEPENDENCIES = LIBNDR \ NDR_SECURITY -LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix $(libclisrcdir)/, ndr_netlogon.o) - -$(eval $(call proto_header_template,$(libclisrcdir)/ndr_netlogon_proto.h,$(LIBCLI_NDR_NETLOGON_OBJ_FILES:.o=.c))) +LIBCLI_NDR_NETLOGON_OBJ_FILES = $(addprefix $(libclinbtsrcdir)/../, ndr_netlogon.o) [SUBSYSTEM::LIBCLI_NETLOGON] PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL LIBCLI_NDR_NETLOGON -LIBCLI_NETLOGON_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ - netlogon.o) - -$(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) - -[SUBSYSTEM::LIBCLI_DRSBLOBS] -PUBLIC_DEPENDENCIES = LIBNDR - -LIBCLI_DRSBLOBS_OBJ_FILES = $(addprefix $(libclisrcdir)/, \ - drsblobs.o) - -$(eval $(call proto_header_template,$(libclisrcdir)/drsblobs_proto.h,$(LIBCLI_DRSBLOBS_OBJ_FILES:.o=.c))) +LIBCLI_NETLOGON_OBJ_FILES = $(addprefix $(libclinbtsrcdir)/, \ + ../netlogon.o) [PYTHON::python_netbios] LIBRARY_REALNAME = samba/netbios.$(SHLIBEXT) PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG -python_netbios_OBJ_FILES = $(libclisrcdir)/nbt/pynbt.o +python_netbios_OBJ_FILES = $(libclinbtsrcdir)/pynbt.o $(python_libcli_nbt_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index e1209e7a54..2f8feb5345 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 "libcli/netlogon.h" +#include "../libcli/netlogon.h" /* a datagram name request diff --git a/source4/libcli/drsblobs.c b/source4/libcli/drsblobs.c deleted file mode 100644 index 126f2ccc40..0000000000 --- a/source4/libcli/drsblobs.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Manually parsed structures found in the DRS protocol - - 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/drsblobs.h" - -/* parser auto-generated by pidl, then hand-modified by abartlet */ - -/* Modified to have 'count' specified */ -static enum ndr_err_code ndr_push_AuthenticationInformationArray_with_count(struct ndr_push *ndr, int ndr_flags, int count, - const struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); - } - } - if (ndr_flags & NDR_BUFFERS) { - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); - } - } - return NDR_ERR_SUCCESS; -} - -/* Modified to have 'count' specified, and to allocate the array */ -static enum ndr_err_code ndr_pull_AuthenticationInformationArray_with_count(struct ndr_pull *ndr, int ndr_flags, int count, struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - TALLOC_CTX *_mem_save_array_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_PULL_ALLOC_N(ndr, r->array, count); - _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); - } - if (ndr_flags & NDR_BUFFERS) { - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); - } - } - return NDR_ERR_SUCCESS; -} - -/* Modified to have 'count' specified */ -_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - ndr_print_struct(ndr, name, "AuthenticationInformationArray"); - ndr->depth++; - ndr->print(ndr, "%s: ARRAY(%d)", "array", (int)1); - ndr->depth++; - for (cntr_array_0=0;cntr_array_0<count;cntr_array_0++) { - char *idx_0=NULL; - if (asprintf(&idx_0, "[%d]", cntr_array_0) != -1) { - ndr_print_AuthenticationInformation(ndr, "array", &r->array[cntr_array_0]); - free(idx_0); - } - } - ndr->depth--; - ndr->depth--; -} - -/* Modified to call AuthenticationInformationArray with 'count' specified */ -_PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r) -{ - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->current)); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous)); - } - if (ndr_flags & NDR_BUFFERS) { - if (r->current) { - NDR_CHECK(ndr_push_relative_ptr2(ndr, r->current)); - NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); - } - if (r->previous) { - NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous)); - NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); - } - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r) -{ - uint32_t _ptr_current; - TALLOC_CTX *_mem_save_current_0; - uint32_t _ptr_previous; - TALLOC_CTX *_mem_save_previous_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_current)); - if (_ptr_current) { - NDR_PULL_ALLOC(ndr, r->current); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->current, _ptr_current)); - } else { - r->current = NULL; - } - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous)); - if (_ptr_previous) { - NDR_PULL_ALLOC(ndr, r->previous); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous, _ptr_previous)); - } else { - r->previous = NULL; - } - } - if (ndr_flags & NDR_BUFFERS) { - if (r->current) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->current)); - _mem_save_current_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->current, 0); - NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_current_0, 0); - ndr->offset = _relative_save_offset; - } - if (r->previous) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous)); - _mem_save_previous_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->previous, 0); - NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_0, 0); - ndr->offset = _relative_save_offset; - } - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r) -{ - ndr_print_struct(ndr, name, "trustAuthInOutBlob"); - ndr->depth++; - ndr_print_uint32(ndr, "count", r->count); - ndr_print_ptr(ndr, "current", r->current); - ndr->depth++; - if (r->current) { - ndr_print_AuthenticationInformationArray_with_count(ndr, "current", r->count, r->current); - } - ndr->depth--; - ndr_print_ptr(ndr, "previous", r->previous); - ndr->depth++; - if (r->previous) { - ndr_print_AuthenticationInformationArray_with_count(ndr, "previous", r->count, r->previous); - } - ndr->depth--; - ndr->depth--; -} - - diff --git a/source4/libcli/drsblobs.h b/source4/libcli/drsblobs.h deleted file mode 100644 index 8fee4114be..0000000000 --- a/source4/libcli/drsblobs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Manually parsed structures found in the DRS protocol - - 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_DRSBLOBS_H__ -#define __LIBCLI_DRSBLOBS_H__ - -#include "librpc/gen_ndr/ndr_drsblobs.h" - -#include "libcli/drsblobs_proto.h" -#endif /* __CLDAP_SERVER_PROTO_H__ */ diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c index 56f931ce19..f12f1ac805 100644 --- a/source4/libcli/finddcs.c +++ b/source4/libcli/finddcs.c @@ -217,7 +217,7 @@ static void fallback_node_status(struct finddcs_state *state) static void fallback_node_status_replied(struct nbt_name_request *name_req) { int i; - struct finddcs_state *state = talloc_get_type(name_req->async.private, struct finddcs_state); + struct finddcs_state *state = talloc_get_type(name_req->async.private_data, struct finddcs_state); state->ctx->status = nbt_name_status_recv(name_req, state, &state->node_status); if (!composite_is_ok(state->ctx)) return; diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 65673116be..b66232c02e 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -387,6 +387,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, if (NT_STATUS_IS_OK(status)) { struct socket_context *sasl_socket; status = gensec_socket_init(conn->gensec, + conn, conn->sock, conn->event.event_ctx, ldap_read_io_handler, diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 844238afdb..fc5863b671 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -77,6 +77,12 @@ static void ldap_connection_dead(struct ldap_connection *conn) { struct ldap_request *req; + talloc_free(conn->sock); /* this will also free event.fde */ + talloc_free(conn->packet); + conn->sock = NULL; + conn->event.fde = NULL; + conn->packet = NULL; + /* return an error for any pending request ... */ while (conn->pending) { req = conn->pending; @@ -87,12 +93,6 @@ static void ldap_connection_dead(struct ldap_connection *conn) req->async.fn(req); } } - - talloc_free(conn->sock); /* this will also free event.fde */ - talloc_free(conn->packet); - conn->sock = NULL; - conn->event.fde = NULL; - conn->packet = NULL; } static void ldap_reconnect(struct ldap_connection *conn); @@ -400,6 +400,7 @@ static void ldap_connect_got_sock(struct composite_context *ctx, talloc_steal(conn, conn->sock); if (conn->ldaps) { struct socket_context *tls_socket; + struct socket_context *tmp_socket; char *cafile = private_path(conn->sock, conn->lp_ctx, lp_tls_cafile(conn->lp_ctx)); if (!cafile || !*cafile) { @@ -414,9 +415,11 @@ static void ldap_connect_got_sock(struct composite_context *ctx, talloc_free(conn->sock); return; } - talloc_unlink(conn, conn->sock); - conn->sock = tls_socket; - talloc_steal(conn, conn->sock); + + /* the original socket, must become a child of the tls socket */ + tmp_socket = conn->sock; + conn->sock = talloc_steal(conn, tls_socket); + talloc_steal(conn->sock, tmp_socket); } conn->packet = packet_init(conn); @@ -432,7 +435,7 @@ static void ldap_connect_got_sock(struct composite_context *ctx, packet_set_error_handler(conn->packet, ldap_error_handler); packet_set_event_context(conn->packet, conn->event.event_ctx); packet_set_fde(conn->packet, conn->event.fde); - packet_set_serialise(conn->packet); +/* packet_set_serialise(conn->packet); */ composite_done(ctx); } diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h deleted file mode 100644 index 0b01365510..0000000000 --- a/source4/libcli/nbt/libnbt.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a raw async NBT library - - 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/>. -*/ - -#ifndef __LIBNBT_H__ -#define __LIBNBT_H__ - -#include "librpc/gen_ndr/nbt.h" -#include "librpc/ndr/libndr.h" - -/* - possible states for pending requests -*/ -enum nbt_request_state {NBT_REQUEST_SEND, - NBT_REQUEST_WAIT, - NBT_REQUEST_DONE, - NBT_REQUEST_TIMEOUT, - NBT_REQUEST_ERROR}; - -/* - a nbt name request -*/ -struct nbt_name_request { - struct nbt_name_request *next, *prev; - - enum nbt_request_state state; - - NTSTATUS status; - - /* the socket this was on */ - struct nbt_name_socket *nbtsock; - - /* where to send the request */ - struct socket_address *dest; - - /* timeout between retries */ - int timeout; - - /* how many retries to send on timeout */ - int num_retries; - - /* whether we have received a WACK */ - bool received_wack; - - /* the timeout event */ - struct timed_event *te; - - /* the name transaction id */ - uint16_t name_trn_id; - - /* is it a reply? */ - bool is_reply; - - /* the encoded request */ - DATA_BLOB encoded; - - /* shall we allow multiple replies? */ - bool allow_multiple_replies; - - unsigned int num_replies; - struct nbt_name_reply { - struct nbt_name_packet *packet; - struct socket_address *dest; - } *replies; - - /* information on what to do on completion */ - struct { - void (*fn)(struct nbt_name_request *); - void *private; - } async; -}; - - - -/* - context structure for operations on name queries -*/ -struct nbt_name_socket { - struct socket_context *sock; - struct event_context *event_ctx; - struct smb_iconv_convenience *iconv_convenience; - - /* a queue of requests pending to be sent */ - struct nbt_name_request *send_queue; - - /* the fd event */ - struct fd_event *fde; - - /* mapping from name_trn_id to pending event */ - struct idr_context *idr; - - /* how many requests are waiting for a reply */ - uint16_t num_pending; - - /* what to do with incoming request packets */ - struct { - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *); - void *private; - } incoming; - - /* what to do with unexpected replies */ - struct { - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *); - void *private; - } unexpected; -}; - - -/* a simple name query */ -struct nbt_name_query { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - bool broadcast; - bool wins_lookup; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - int16_t num_addrs; - const char **reply_addrs; - } out; -}; - -/* a simple name status query */ -struct nbt_name_status { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - struct nbt_rdata_status status; - } out; -}; - -/* a name registration request */ -struct nbt_name_register { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool register_demand; - bool broadcast; - bool multi_homed; - uint32_t ttl; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -/* a send 3 times then demand name broadcast name registration */ -struct nbt_name_register_bcast { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - uint32_t ttl; - } in; -}; - - -/* wins name register with multiple wins servers to try and multiple - addresses to register */ -struct nbt_name_register_wins { - struct { - struct nbt_name name; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - uint16_t nb_flags; - uint32_t ttl; - } in; - struct { - const char *wins_server; - uint8_t rcode; - } out; -}; - - - -/* a name refresh request */ -struct nbt_name_refresh { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool broadcast; - uint32_t ttl; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -/* wins name refresh with multiple wins servers to try and multiple - addresses to register */ -struct nbt_name_refresh_wins { - struct { - struct nbt_name name; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - uint16_t nb_flags; - uint32_t ttl; - } in; - struct { - const char *wins_server; - uint8_t rcode; - } out; -}; - - -/* a name release request */ -struct nbt_name_release { - struct { - struct nbt_name name; - const char *dest_addr; - uint16_t dest_port; - const char *address; - uint16_t nb_flags; - bool broadcast; - int timeout; /* in seconds */ - int retries; - } in; - struct { - const char *reply_from; - struct nbt_name name; - const char *reply_addr; - uint8_t rcode; - } out; -}; - -struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct smb_iconv_convenience *iconv_convenience); -struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, - struct nbt_name_query *io); -NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io); -struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, - struct nbt_name_status *io); -NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io); -NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io); - -NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname); -NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name); -NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name); -void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type); -char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name); -NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io); -NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); -NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io); -NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io); -struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register *io); -NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io); - -struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, - struct nbt_name_release *io); - -NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io); - -NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *), - void *private); -NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request); - - -NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *) -NDR_SCALAR_PROTO(nbt_string, const char *) -NDR_BUFFER_PROTO(nbt_name, struct nbt_name) -NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode); - -struct composite_context; -struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io); -NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c); -struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io); -NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io); - - -#endif /* __LIBNBT_H__ */ diff --git a/source4/libcli/nbt/man/nmblookup.1.xml b/source4/libcli/nbt/man/nmblookup.1.xml new file mode 100644 index 0000000000..85640da033 --- /dev/null +++ b/source4/libcli/nbt/man/nmblookup.1.xml @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> +<refentry id="nmblookup"> + +<refmeta> + <refentrytitle>nmblookup</refentrytitle> + <manvolnum>1</manvolnum> + <refmiscinfo class="source">Samba</refmiscinfo> + <refmiscinfo class="manual">User Commands</refmiscinfo> + <refmiscinfo class="version">3.2</refmiscinfo> +</refmeta> + + +<refnamediv> + <refname>nmblookup</refname> + <refpurpose>NetBIOS over TCP/IP client used to lookup NetBIOS + names</refpurpose> +</refnamediv> + +<refsynopsisdiv> + <cmdsynopsis> + <command>nmblookup</command> + <arg choice="opt">-M</arg> + <arg choice="opt">-R</arg> + <arg choice="opt">-S</arg> + <arg choice="opt">-r</arg> + <arg choice="opt">-A</arg> + <arg choice="opt">-h</arg> + <arg choice="opt">-B <broadcast address></arg> + <arg choice="opt">-U <unicast address></arg> + <arg choice="opt">-d <debug level></arg> + <arg choice="opt">-s <smb config file></arg> + <arg choice="opt">-i <NetBIOS scope></arg> + <arg choice="opt">-T</arg> + <arg choice="opt">-f</arg> + <arg choice="req">name</arg> + </cmdsynopsis> +</refsynopsisdiv> + +<refsect1> + <title>DESCRIPTION</title> + + <para>This tool is part of the <citerefentry><refentrytitle>samba</refentrytitle> + <manvolnum>7</manvolnum></citerefentry> suite.</para> + + <para><command>nmblookup</command> is used to query NetBIOS names + and map them to IP addresses in a network using NetBIOS over TCP/IP + queries. The options allow the name queries to be directed at a + particular IP broadcast area or to a particular machine. All queries + are done over UDP.</para> +</refsect1> + +<refsect1> + <title>OPTIONS</title> + + <variablelist> + <varlistentry> + <term>-M</term> + <listitem><para>Searches for a master browser by looking + up the NetBIOS name <replaceable>name</replaceable> with a + type of <constant>0x1d</constant>. If <replaceable> + name</replaceable> is "-" then it does a lookup on the special name + <constant>__MSBROWSE__</constant>. Please note that in order to + use the name "-", you need to make sure "-" isn't parsed as an + argument, e.g. use : + <userinput>nmblookup -M -- -</userinput>.</para></listitem> + </varlistentry> + + <varlistentry> + <term>-R</term> + <listitem><para>Set the recursion desired bit in the packet + to do a recursive lookup. This is used when sending a name + query to a machine running a WINS server and the user wishes + to query the names in the WINS server. If this bit is unset + the normal (broadcast responding) NetBIOS processing code + on a machine is used instead. See RFC1001, RFC1002 for details. + </para></listitem> + </varlistentry> + + <varlistentry> + <term>-S</term> + <listitem><para>Once the name query has returned an IP + address then do a node status query as well. A node status + query returns the NetBIOS names registered by a host. + </para></listitem> + </varlistentry> + + + <varlistentry> + <term>-r</term> + <listitem><para>Try and bind to UDP port 137 to send and receive UDP + datagrams. The reason for this option is a bug in Windows 95 + where it ignores the source port of the requesting packet + and only replies to UDP port 137. Unfortunately, on most UNIX + systems root privilege is needed to bind to this port, and + in addition, if the <citerefentry><refentrytitle>nmbd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> daemon is running on this machine it also binds to this port. + </para></listitem> + </varlistentry> + + + <varlistentry> + <term>-A</term> + <listitem><para>Interpret <replaceable>name</replaceable> as + an IP Address and do a node status query on this address.</para> + </listitem> + </varlistentry> + + + + &popt.common.connection; + &stdarg.help; + + <varlistentry> + <term>-B <broadcast address></term> + <listitem><para>Send the query to the given broadcast address. Without + this option the default behavior of nmblookup is to send the + query to the broadcast address of the network interfaces as + either auto-detected or defined in the <ulink + url="smb.conf.5.html#INTERFACES"><parameter>interfaces</parameter> + </ulink> parameter of the <citerefentry><refentrytitle>smb.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> file. + </para></listitem> + </varlistentry> + + + + <varlistentry> + <term>-U <unicast address></term> + <listitem><para>Do a unicast query to the specified address or + host <replaceable>unicast address</replaceable>. This option + (along with the <parameter>-R</parameter> option) is needed to + query a WINS server.</para></listitem> + </varlistentry> + + &stdarg.server.debug; + &popt.common.samba; + + <varlistentry> + <term>-T</term> + <listitem><para>This causes any IP addresses found in the + lookup to be looked up via a reverse DNS lookup into a + DNS name, and printed out before each</para> + + <para><emphasis>IP address .... NetBIOS name</emphasis></para> + + <para> pair that is the normal output.</para></listitem> + </varlistentry> + + <varlistentry> + <term>-f</term> + <listitem><para> + Show which flags apply to the name that has been looked up. Possible + answers are zero or more of: Response, Authoritative, + Truncated, Recursion_Desired, Recursion_Available, Broadcast. + </para></listitem> + </varlistentry> + + + <varlistentry> + <term>name</term> + <listitem><para>This is the NetBIOS name being queried. Depending + upon the previous options this may be a NetBIOS name or IP address. + If a NetBIOS name then the different name types may be specified + by appending '#<type>' to the name. This name may also be + '*', which will return all registered names within a broadcast + area.</para></listitem> + </varlistentry> + </variablelist> +</refsect1> + + +<refsect1> + <title>EXAMPLES</title> + + <para><command>nmblookup</command> can be used to query + a WINS server (in the same way <command>nslookup</command> is + used to query DNS servers). To query a WINS server, <command>nmblookup</command> + must be called like this:</para> + + <para><command>nmblookup -U server -R 'name'</command></para> + + <para>For example, running :</para> + + <para><command>nmblookup -U samba.org -R 'IRIX#1B'</command></para> + + <para>would query the WINS server samba.org for the domain + master browser (1B name type) for the IRIX workgroup.</para> +</refsect1> + +<refsect1> + <title>VERSION</title> + + <para>This man page is correct for version 3 of + the Samba suite.</para> +</refsect1> + +<refsect1> + <title>SEE ALSO</title> + <para><citerefentry><refentrytitle>nmbd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>samba</refentrytitle> + <manvolnum>7</manvolnum></citerefentry>, and <citerefentry><refentrytitle>smb.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>.</para> +</refsect1> + +<refsect1> + <title>AUTHOR</title> + + <para>The original Samba software and related utilities + were created by Andrew Tridgell. Samba is now developed + by the Samba Team as an Open Source project similar + to the way the Linux kernel is developed.</para> + + <para>The original Samba man pages were written by Karl Auer. + The man page sources were converted to YODL format (another + excellent piece of Open Source software, available at <ulink url="ftp://ftp.icce.rug.nl/pub/unix/"> + ftp://ftp.icce.rug.nl/pub/unix/</ulink>) and updated for the Samba 2.0 + release by Jeremy Allison. The conversion to DocBook for + Samba 2.2 was done by Gerald Carter. The conversion to DocBook + XML 4.2 for Samba 3.0 was done by Alexander Bokovoy.</para> +</refsect1> + +</refentry> diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c deleted file mode 100644 index 2e1bcd818b..0000000000 --- a/source4/libcli/nbt/namequery.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - make nbt name query 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/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "lib/socket/socket.h" -#include "param/param.h" - -/** - send a nbt name query -*/ -_PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, - struct nbt_name_query *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->operation = NBT_OPCODE_QUERY; - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - if (io->in.wins_lookup) { - packet->operation |= NBT_FLAG_RECURSION_DESIRED; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/** - wait for a name query reply -*/ -_PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - int i; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if ((packet->operation & NBT_RCODE) != 0) { - status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); - talloc_free(req); - return status; - } - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return status; - } - - io->out.name = packet->answers[0].name; - io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6; - io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs+1); - if (io->out.reply_addrs == NULL) { - talloc_free(req); - return NT_STATUS_NO_MEMORY; - } - - for (i=0;i<io->out.num_addrs;i++) { - io->out.reply_addrs[i] = talloc_steal(io->out.reply_addrs, - packet->answers[0].rdata.netbios.addresses[i].ipaddr); - } - io->out.reply_addrs[i] = NULL; - - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/** - wait for a name query reply -*/ -_PUBLIC_ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_query *io) -{ - struct nbt_name_request *req = nbt_name_query_send(nbtsock, io); - return nbt_name_query_recv(req, mem_ctx, io); -} - - -/** - send a nbt name status -*/ -_PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, - struct nbt_name_status *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->operation = NBT_OPCODE_QUERY; - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_STATUS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/** - wait for a name status reply -*/ -_PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - int i; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if ((packet->operation & NBT_RCODE) != 0) { - status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); - talloc_free(req); - return status; - } - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_STATUS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.name = packet->answers[0].name; - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - io->out.status = packet->answers[0].rdata.status; - talloc_steal(mem_ctx, io->out.status.names); - for (i=0;i<io->out.status.num_names;i++) { - talloc_steal(io->out.status.names, io->out.status.names[i].name); - } - - - talloc_free(req); - - return NT_STATUS_OK; -} - -/** - wait for a name status reply -*/ -_PUBLIC_ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_status *io) -{ - struct nbt_name_request *req = nbt_name_status_send(nbtsock, io); - return nbt_name_status_recv(req, mem_ctx, io); -} - - diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c deleted file mode 100644 index b372e4a3f3..0000000000 --- a/source4/libcli/nbt/namerefresh.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - send out a name refresh request - - 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/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "libcli/composite/composite.h" -#include "lib/socket/socket.h" -#include "param/param.h" - -/* - send a nbt name refresh request -*/ -struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->arcount = 1; - packet->operation = NBT_OPCODE_REFRESH; - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - packet->additional = talloc_array(packet, struct nbt_res_rec, 1); - if (packet->additional == NULL) goto failed; - - packet->additional[0].name = io->in.name; - packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; - packet->additional[0].rr_class = NBT_QCLASS_IP; - packet->additional[0].ttl = io->in.ttl; - packet->additional[0].rdata.netbios.length = 6; - packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, - struct nbt_rdata_address, 1); - if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; - packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = - talloc_strdup(packet->additional, io->in.address); - - dest = socket_address_from_strings(nbtsock, - nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/* - wait for a refresh reply -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.rcode = packet->operation & NBT_RCODE; - io->out.name = packet->answers[0].name; - if (packet->answers[0].rdata.netbios.length < 6) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - io->out.reply_addr = talloc_steal(mem_ctx, - packet->answers[0].rdata.netbios.addresses[0].ipaddr); - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/* - synchronous name refresh request -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io) -{ - struct nbt_name_request *req = nbt_name_refresh_send(nbtsock, io); - return nbt_name_refresh_recv(req, mem_ctx, io); -} - - - -/** - a wins name refresh with multiple WINS servers and multiple - addresses to refresh. Try each WINS server in turn, until we get a - reply for each address -*/ -struct refresh_wins_state { - struct nbt_name_socket *nbtsock; - struct nbt_name_refresh *io; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - int address_idx; - struct nbt_name_request *req; -}; - - -/** - state handler for WINS multi-homed multi-server name refresh -*/ -static void name_refresh_wins_handler(struct nbt_name_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - struct refresh_wins_state *state = talloc_get_type(c->private_data, - struct refresh_wins_state); - NTSTATUS status; - - status = nbt_name_refresh_recv(state->req, state, state->io); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - /* the refresh timed out - try the next WINS server */ - state->wins_servers++; - state->address_idx = 0; - if (state->wins_servers[0] == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - goto done; - } - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = state->addresses[0]; - state->req = nbt_name_refresh_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_refresh_wins_handler; - state->req->async.private = c; - } - } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - if (state->io->out.rcode == 0 && - state->addresses[state->address_idx+1] != NULL) { - /* refresh our next address */ - state->io->in.address = state->addresses[++(state->address_idx)]; - state->req = nbt_name_refresh_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_refresh_wins_handler; - state->req->async.private = c; - } - } else { - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - } - } - -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/** - the async send call for a multi-server WINS refresh -*/ -_PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io) -{ - struct composite_context *c; - struct refresh_wins_state *state; - - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct refresh_wins_state); - if (state == NULL) goto failed; - - state->io = talloc(state, struct nbt_name_refresh); - if (state->io == NULL) goto failed; - - state->wins_port = io->in.wins_port; - state->wins_servers = str_list_copy(state, io->in.wins_servers); - if (state->wins_servers == NULL || - state->wins_servers[0] == NULL) goto failed; - - state->addresses = str_list_copy(state, io->in.addresses); - if (state->addresses == NULL || - state->addresses[0] == NULL) goto failed; - - state->io->in.name = io->in.name; - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = io->in.addresses[0]; - state->io->in.nb_flags = io->in.nb_flags; - state->io->in.broadcast = false; - state->io->in.ttl = io->in.ttl; - state->io->in.timeout = 2; - state->io->in.retries = 2; - - state->nbtsock = nbtsock; - state->address_idx = 0; - - state->req = nbt_name_refresh_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = name_refresh_wins_handler; - state->req->async.private = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; - - return c; - -failed: - talloc_free(c); - return NULL; -} - -/* - multi-homed WINS name refresh - recv side -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io) -{ - NTSTATUS status; - status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct refresh_wins_state *state = - talloc_get_type(c->private_data, struct refresh_wins_state); - io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); - io->out.rcode = state->io->out.rcode; - } - talloc_free(c); - return status; -} - -/* - multi-homed WINS refresh - sync interface -*/ -_PUBLIC_ NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io) -{ - struct composite_context *c = nbt_name_refresh_wins_send(nbtsock, io); - return nbt_name_refresh_wins_recv(c, mem_ctx, io); -} diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c deleted file mode 100644 index 9c5ae43d40..0000000000 --- a/source4/libcli/nbt/nameregister.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - send out a name registration request - - 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/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "libcli/composite/composite.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -/* - send a nbt name registration request -*/ -struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->arcount = 1; - if (io->in.multi_homed) { - packet->operation = NBT_OPCODE_MULTI_HOME_REG; - } else { - packet->operation = NBT_OPCODE_REGISTER; - } - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - if (io->in.register_demand) { - packet->operation |= NBT_FLAG_RECURSION_DESIRED; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - packet->additional = talloc_array(packet, struct nbt_res_rec, 1); - if (packet->additional == NULL) goto failed; - - packet->additional[0].name = io->in.name; - packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; - packet->additional[0].rr_class = NBT_QCLASS_IP; - packet->additional[0].ttl = io->in.ttl; - packet->additional[0].rdata.netbios.length = 6; - packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, - struct nbt_rdata_address, 1); - if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; - packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = - talloc_strdup(packet->additional, io->in.address); - if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/* - wait for a registration reply -*/ -_PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.rcode = packet->operation & NBT_RCODE; - io->out.name = packet->answers[0].name; - if (packet->answers[0].rdata.netbios.length < 6) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - io->out.reply_addr = talloc_steal(mem_ctx, - packet->answers[0].rdata.netbios.addresses[0].ipaddr); - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/* - synchronous name registration request -*/ -_PUBLIC_ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_register *io) -{ - struct nbt_name_request *req = nbt_name_register_send(nbtsock, io); - return nbt_name_register_recv(req, mem_ctx, io); -} - - -/* - a 4 step broadcast registration. 3 lots of name registration requests, followed by - a name registration demand -*/ -struct register_bcast_state { - struct nbt_name_socket *nbtsock; - struct nbt_name_register *io; - struct nbt_name_request *req; -}; - - -/* - state handler for 4 stage name registration -*/ -static void name_register_bcast_handler(struct nbt_name_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, struct composite_context); - struct register_bcast_state *state = talloc_get_type(c->private_data, struct register_bcast_state); - NTSTATUS status; - - status = nbt_name_register_recv(state->req, state, state->io); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - if (state->io->in.register_demand == true) { - /* all done */ - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - goto done; - } - - /* the registration timed out - good, send the demand */ - state->io->in.register_demand = true; - state->io->in.retries = 0; - state->req = nbt_name_register_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_register_bcast_handler; - state->req->async.private = c; - } - } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_CONFLICTING_ADDRESSES; - DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n", - state->io->out.reply_from, - nbt_name_string(state, &state->io->out.name), - state->io->out.reply_addr, - state->io->out.rcode)); - } - -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - the async send call for a 4 stage name registration -*/ -_PUBLIC_ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io) -{ - struct composite_context *c; - struct register_bcast_state *state; - - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct register_bcast_state); - if (state == NULL) goto failed; - - state->io = talloc(state, struct nbt_name_register); - if (state->io == NULL) goto failed; - - state->io->in.name = io->in.name; - state->io->in.dest_addr = io->in.dest_addr; - state->io->in.dest_port = io->in.dest_port; - state->io->in.address = io->in.address; - state->io->in.nb_flags = io->in.nb_flags; - state->io->in.register_demand = false; - state->io->in.broadcast = true; - state->io->in.multi_homed = false; - state->io->in.ttl = io->in.ttl; - state->io->in.timeout = 1; - state->io->in.retries = 2; - - state->nbtsock = nbtsock; - - state->req = nbt_name_register_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = name_register_bcast_handler; - state->req->async.private = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; - - return c; - -failed: - talloc_free(c); - return NULL; -} - -/* - broadcast 4 part name register - recv -*/ -_PUBLIC_ NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c) -{ - NTSTATUS status; - status = composite_wait(c); - talloc_free(c); - return status; -} - -/* - broadcast 4 part name register - sync interface -*/ -NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock, - struct nbt_name_register_bcast *io) -{ - struct composite_context *c = nbt_name_register_bcast_send(nbtsock, io); - return nbt_name_register_bcast_recv(c); -} - - -/* - a wins name register with multiple WINS servers and multiple - addresses to register. Try each WINS server in turn, until we get a - reply for each address -*/ -struct register_wins_state { - struct nbt_name_socket *nbtsock; - struct nbt_name_register *io; - const char **wins_servers; - uint16_t wins_port; - const char **addresses; - int address_idx; - struct nbt_name_request *req; -}; - - -/* - state handler for WINS multi-homed multi-server name register -*/ -static void name_register_wins_handler(struct nbt_name_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private, - struct composite_context); - struct register_wins_state *state = talloc_get_type(c->private_data, - struct register_wins_state); - NTSTATUS status; - - status = nbt_name_register_recv(state->req, state, state->io); - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - /* the register timed out - try the next WINS server */ - state->wins_servers++; - state->address_idx = 0; - if (state->wins_servers[0] == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - goto done; - } - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = state->addresses[0]; - state->req = nbt_name_register_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_register_wins_handler; - state->req->async.private = c; - } - } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - if (state->io->out.rcode == 0 && - state->addresses[state->address_idx+1] != NULL) { - /* register our next address */ - state->io->in.address = state->addresses[++(state->address_idx)]; - state->req = nbt_name_register_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = name_register_wins_handler; - state->req->async.private = c; - } - } else { - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - } - } - -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); - } -} - -/* - the async send call for a multi-server WINS register -*/ -_PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_register_wins *io) -{ - struct composite_context *c; - struct register_wins_state *state; - - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct register_wins_state); - if (state == NULL) goto failed; - - state->io = talloc(state, struct nbt_name_register); - if (state->io == NULL) goto failed; - - state->wins_port = io->in.wins_port; - state->wins_servers = str_list_copy(state, io->in.wins_servers); - if (state->wins_servers == NULL || - state->wins_servers[0] == NULL) goto failed; - - state->addresses = str_list_copy(state, io->in.addresses); - if (state->addresses == NULL || - state->addresses[0] == NULL) goto failed; - - state->io->in.name = io->in.name; - state->io->in.dest_addr = state->wins_servers[0]; - state->io->in.dest_port = state->wins_port; - state->io->in.address = io->in.addresses[0]; - state->io->in.nb_flags = io->in.nb_flags; - state->io->in.broadcast = false; - state->io->in.register_demand = false; - state->io->in.multi_homed = (io->in.nb_flags & NBT_NM_GROUP)?false:true; - state->io->in.ttl = io->in.ttl; - state->io->in.timeout = 3; - state->io->in.retries = 2; - - state->nbtsock = nbtsock; - state->address_idx = 0; - - state->req = nbt_name_register_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = name_register_wins_handler; - state->req->async.private = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; - - return c; - -failed: - talloc_free(c); - return NULL; -} - -/* - multi-homed WINS name register - recv side -*/ -_PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io) -{ - NTSTATUS status; - status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct register_wins_state *state = - talloc_get_type(c->private_data, struct register_wins_state); - io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); - io->out.rcode = state->io->out.rcode; - } - talloc_free(c); - return status; -} - -/* - multi-homed WINS register - sync interface -*/ -_PUBLIC_ NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_register_wins *io) -{ - struct composite_context *c = nbt_name_register_wins_send(nbtsock, io); - return nbt_name_register_wins_recv(c, mem_ctx, io); -} diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c deleted file mode 100644 index ba3af41752..0000000000 --- a/source4/libcli/nbt/namerelease.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - send out a name release request - - 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/nbt/libnbt.h" -#include "libcli/nbt/nbt_proto.h" -#include "lib/socket/socket.h" -#include "param/param.h" - -/* - send a nbt name release request -*/ -_PUBLIC_ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, - struct nbt_name_release *io) -{ - struct nbt_name_request *req; - struct nbt_name_packet *packet; - struct socket_address *dest; - - packet = talloc_zero(nbtsock, struct nbt_name_packet); - if (packet == NULL) return NULL; - - packet->qdcount = 1; - packet->arcount = 1; - packet->operation = NBT_OPCODE_RELEASE; - if (io->in.broadcast) { - packet->operation |= NBT_FLAG_BROADCAST; - } - - packet->questions = talloc_array(packet, struct nbt_name_question, 1); - if (packet->questions == NULL) goto failed; - - packet->questions[0].name = io->in.name; - packet->questions[0].question_type = NBT_QTYPE_NETBIOS; - packet->questions[0].question_class = NBT_QCLASS_IP; - - packet->additional = talloc_array(packet, struct nbt_res_rec, 1); - if (packet->additional == NULL) goto failed; - - packet->additional[0].name = io->in.name; - packet->additional[0].rr_type = NBT_QTYPE_NETBIOS; - packet->additional[0].rr_class = NBT_QCLASS_IP; - packet->additional[0].ttl = 0; - packet->additional[0].rdata.netbios.length = 6; - packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional, - struct nbt_rdata_address, 1); - if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed; - packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags; - packet->additional[0].rdata.netbios.addresses[0].ipaddr = - talloc_strdup(packet->additional, io->in.address); - - dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, - io->in.dest_addr, io->in.dest_port); - if (dest == NULL) goto failed; - req = nbt_name_request_send(nbtsock, dest, packet, - io->in.timeout, io->in.retries, false); - if (req == NULL) goto failed; - - talloc_free(packet); - return req; - -failed: - talloc_free(packet); - return NULL; -} - -/* - wait for a release reply -*/ -_PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io) -{ - NTSTATUS status; - struct nbt_name_packet *packet; - - status = nbt_name_request_recv(req); - if (!NT_STATUS_IS_OK(status) || - req->num_replies == 0) { - talloc_free(req); - return status; - } - - packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); - - if (packet->ancount != 1 || - packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || - packet->answers[0].rr_class != NBT_QCLASS_IP) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - io->out.rcode = packet->operation & NBT_RCODE; - io->out.name = packet->answers[0].name; - if (packet->answers[0].rdata.netbios.length < 6) { - talloc_free(req); - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - io->out.reply_addr = talloc_steal(mem_ctx, - packet->answers[0].rdata.netbios.addresses[0].ipaddr); - talloc_steal(mem_ctx, io->out.name.name); - talloc_steal(mem_ctx, io->out.name.scope); - - talloc_free(req); - - return NT_STATUS_OK; -} - -/* - synchronous name release request -*/ -_PUBLIC_ NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, struct nbt_name_release *io) -{ - struct nbt_name_request *req = nbt_name_release_send(nbtsock, io); - return nbt_name_release_recv(req, mem_ctx, io); -} diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c deleted file mode 100644 index 97ae2e9d72..0000000000 --- a/source4/libcli/nbt/nbtname.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - manipulate nbt name structures - - 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/>. -*/ - -/* - see rfc1002 for the detailed format of compressed names -*/ - -#include "includes.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "system/locale.h" -#include "param/param.h" - -/* don't allow an unlimited number of name components */ -#define MAX_COMPONENTS 10 - -/** - print a nbt string -*/ -_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) -{ - ndr_print_string(ndr, name, s); -} - -/* - pull one component of a nbt_string -*/ -static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr, - uint8_t **component, - uint32_t *offset, - uint32_t *max_offset) -{ - uint8_t len; - uint_t loops = 0; - while (loops < 5) { - if (*offset >= ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - len = ndr->data[*offset]; - if (len == 0) { - *offset += 1; - *max_offset = MAX(*max_offset, *offset); - *component = NULL; - return NDR_ERR_SUCCESS; - } - if ((len & 0xC0) == 0xC0) { - /* its a label pointer */ - if (1 + *offset >= ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - *max_offset = MAX(*max_offset, *offset + 2); - *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset]; - *max_offset = MAX(*max_offset, *offset); - loops++; - continue; - } - if ((len & 0xC0) != 0) { - /* its a reserved length field */ - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - if (*offset + len + 2 > ndr->data_size) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME component"); - } - *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len); - NDR_ERR_HAVE_NO_MEMORY(*component); - *offset += len + 1; - *max_offset = MAX(*max_offset, *offset); - return NDR_ERR_SUCCESS; - } - - /* too many pointers */ - return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component"); -} - -/** - pull a nbt_string from the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) -{ - uint32_t offset = ndr->offset; - uint32_t max_offset = offset; - unsigned num_components; - char *name; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - name = NULL; - - /* break up name into a list of components */ - for (num_components=0;num_components<MAX_COMPONENTS;num_components++) { - uint8_t *component; - NDR_CHECK(ndr_pull_component(ndr, &component, &offset, &max_offset)); - if (component == NULL) break; - if (name) { - name = talloc_asprintf_append_buffer(name, ".%s", component); - NDR_ERR_HAVE_NO_MEMORY(name); - } else { - name = (char *)component; - } - } - if (num_components == MAX_COMPONENTS) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "BAD NBT NAME too many components"); - } - if (num_components == 0) { - name = talloc_strdup(ndr, ""); - NDR_ERR_HAVE_NO_MEMORY(name); - } - - (*s) = name; - ndr->offset = max_offset; - - return NDR_ERR_SUCCESS; -} - -/** - push a nbt string to the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s) -{ - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - while (s && *s) { - enum ndr_err_code ndr_err; - char *compname; - size_t complen; - uint32_t offset; - - /* see if we have pushed the remaing string allready, - * if so we use a label pointer to this string - */ - ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - uint8_t b[2]; - - if (offset > 0x3FFF) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "offset for nbt string label pointer %u[%08X] > 0x00003FFF", - offset, offset); - } - - b[0] = 0xC0 | (offset>>8); - b[1] = (offset & 0xFF); - - return ndr_push_bytes(ndr, b, 2); - } - - complen = strcspn(s, "."); - - /* we need to make sure the length fits into 6 bytes */ - if (complen >= 0x3F) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "component length %u[%08X] > 0x00003F", - (unsigned)complen, (unsigned)complen); - } - - compname = talloc_asprintf(ndr, "%c%*.*s", - (unsigned char)complen, - (unsigned char)complen, - (unsigned char)complen, s); - NDR_ERR_HAVE_NO_MEMORY(compname); - - /* remember the current componemt + the rest of the string - * so it can be reused later - */ - NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset)); - - /* push just this component into the blob */ - NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1)); - talloc_free(compname); - - s += complen; - if (*s == '.') s++; - } - - /* if we reach the end of the string and have pushed the last component - * without using a label pointer, we need to terminate the string - */ - return ndr_push_bytes(ndr, (const uint8_t *)"", 1); -} - - -/* - decompress a 'compressed' name component - */ -static bool decompress_name(char *name, enum nbt_name_type *type) -{ - int i; - for (i=0;name[2*i];i++) { - uint8_t c1 = name[2*i]; - uint8_t c2 = name[1+(2*i)]; - if (c1 < 'A' || c1 > 'P' || - c2 < 'A' || c2 > 'P') { - return false; - } - name[i] = ((c1-'A')<<4) | (c2-'A'); - } - name[i] = 0; - if (i == 16) { - *type = (enum nbt_name_type)(name[15]); - name[15] = 0; - i--; - } else { - *type = NBT_NAME_CLIENT; - } - - /* trim trailing spaces */ - for (;i>0 && name[i-1]==' ';i--) { - name[i-1] = 0; - } - - return true; -} - - -/* - compress a name component - */ -static uint8_t *compress_name(TALLOC_CTX *mem_ctx, - const uint8_t *name, enum nbt_name_type type) -{ - uint8_t *cname; - int i; - uint8_t pad_char; - - if (strlen((const char *)name) > 15) { - return NULL; - } - - cname = talloc_array(mem_ctx, uint8_t, 33); - if (cname == NULL) return NULL; - - for (i=0;name[i];i++) { - cname[2*i] = 'A' + (name[i]>>4); - cname[1+2*i] = 'A' + (name[i]&0xF); - } - if (strcmp((const char *)name, "*") == 0) { - pad_char = 0; - } else { - pad_char = ' '; - } - for (;i<15;i++) { - cname[2*i] = 'A' + (pad_char>>4); - cname[1+2*i] = 'A' + (pad_char&0xF); - } - - pad_char = type; - cname[2*i] = 'A' + (pad_char>>4); - cname[1+2*i] = 'A' + (pad_char&0xF); - - cname[32] = 0; - return cname; -} - - -/** - pull a nbt name from the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) -{ - uint8_t *scope; - char *cname; - const char *s; - bool ok; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s)); - - scope = (uint8_t *)strchr(s, '.'); - if (scope) { - *scope = 0; - r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]); - NDR_ERR_HAVE_NO_MEMORY(r->scope); - } else { - r->scope = NULL; - } - - cname = discard_const_p(char, s); - - /* the first component is limited to 16 bytes in the DOS charset, - which is 32 in the 'compressed' form */ - if (strlen(cname) > 32) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "NBT NAME cname > 32"); - } - - /* decompress the first component */ - ok = decompress_name(cname, &r->type); - if (!ok) { - return ndr_pull_error(ndr, NDR_ERR_STRING, - "NBT NAME failed to decompress"); - } - - r->name = talloc_strdup(ndr->current_mem_ctx, cname); - NDR_ERR_HAVE_NO_MEMORY(r->name); - - talloc_free(cname); - - return NDR_ERR_SUCCESS; -} - -/** - push a nbt name to the wire -*/ -_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) -{ - uint8_t *cname, *fullname; - enum ndr_err_code ndr_err; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - if (strlen(r->name) > 15) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "nbt_name longer as 15 chars: %s", - r->name); - } - - cname = compress_name(ndr, (const uint8_t *)r->name, r->type); - NDR_ERR_HAVE_NO_MEMORY(cname); - - if (r->scope) { - fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope); - NDR_ERR_HAVE_NO_MEMORY(fullname); - talloc_free(cname); - } else { - fullname = cname; - } - - ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname); - - return ndr_err; -} - - -/** - copy a nbt name structure -*/ -_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname) -{ - *newname = *name; - newname->name = talloc_strdup(mem_ctx, newname->name); - NT_STATUS_HAVE_NO_MEMORY(newname->name); - newname->scope = talloc_strdup(mem_ctx, newname->scope); - if (name->scope) { - NT_STATUS_HAVE_NO_MEMORY(newname->scope); - } - return NT_STATUS_OK; -} - -/** - push a nbt name into a blob -*/ -_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name) -{ - enum ndr_err_code ndr_err; - - ndr_err = ndr_push_struct_blob(blob, mem_ctx, iconv_convenience, name, (ndr_push_flags_fn_t)ndr_push_nbt_name); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - return NT_STATUS_OK; -} - -/** - pull a nbt name from a blob -*/ -_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name) -{ - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, name, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - return NT_STATUS_OK; -} - - -/** - choose a name to use when calling a server in a NBT session request. - we use heuristics to see if the name we have been given is a IP - address, or a too-long name. If it is then use *SMBSERVER, or a - truncated name -*/ -_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx, - struct nbt_name *n, const char *name, int type) -{ - n->scope = NULL; - n->type = type; - - if (is_ipaddress(name) || name == NULL) { - n->name = "*SMBSERVER"; - return; - } - if (strlen(name) > 15) { - const char *p = strchr(name, '.'); - char *s; - if (p - name > 15) { - n->name = "*SMBSERVER"; - return; - } - s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name)); - n->name = strupper_talloc(mem_ctx, s); - return; - } - - n->name = strupper_talloc(mem_ctx, name); -} - - -/* - escape a string into a form containing only a small set of characters, - the rest is hex encoded. This is similar to URL encoding -*/ -static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s) -{ - int i, len; - char *ret; - const char *valid_chars = "_-.$@ "; -#define NBT_CHAR_ALLOW(c) (isalnum((unsigned char)c) || strchr(valid_chars, c)) - - for (len=i=0;s[i];i++,len++) { - if (!NBT_CHAR_ALLOW(s[i])) { - len += 2; - } - } - - ret = talloc_array(mem_ctx, char, len+1); - if (ret == NULL) return NULL; - - for (len=i=0;s[i];i++) { - if (NBT_CHAR_ALLOW(s[i])) { - ret[len++] = s[i]; - } else { - snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]); - len += 3; - } - } - ret[len] = 0; - - return ret; -} - - -/** - form a string for a NBT name -*/ -_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name) -{ - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - char *ret; - if (name->scope) { - ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s", - nbt_hex_encode(tmp_ctx, name->name), - name->type, - nbt_hex_encode(tmp_ctx, name->scope)); - } else { - ret = talloc_asprintf(mem_ctx, "%s<%02x>", - nbt_hex_encode(tmp_ctx, name->name), - name->type); - } - talloc_free(tmp_ctx); - return ret; -} - -/** - pull a nbt name, WINS Replication uses another on wire format for nbt name -*/ -_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r) -{ - struct nbt_name *r; - uint8_t *namebuf; - uint32_t namebuf_len; - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &namebuf_len)); - if (namebuf_len < 1 || namebuf_len > 255) { - return ndr_pull_error(ndr, NDR_ERR_ALLOC, "value out of range"); - } - NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); - - NDR_PULL_ALLOC(ndr, r); - - /* oh wow, what a nasty bug in windows ... */ - if (namebuf[0] == 0x1b && namebuf_len >= 16) { - namebuf[0] = namebuf[15]; - namebuf[15] = 0x1b; - } - - if (namebuf_len < 17) { - r->type = 0x00; - - r->name = talloc_strndup(r, (char *)namebuf, namebuf_len); - if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - r->scope= NULL; - - talloc_free(namebuf); - *_r = r; - return NDR_ERR_SUCCESS; - } - - r->type = namebuf[15]; - - namebuf[15] = '\0'; - trim_string((char *)namebuf, NULL, " "); - r->name = talloc_strdup(r, (char *)namebuf); - if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - if (namebuf_len > 18) { - r->scope = talloc_strndup(r, (char *)(namebuf+17), namebuf_len-17); - if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory"); - } else { - r->scope = NULL; - } - - talloc_free(namebuf); - *_r = r; - return NDR_ERR_SUCCESS; -} - -/** - push a nbt name, WINS Replication uses another on wire format for nbt name -*/ -_PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r) -{ - uint8_t *namebuf; - uint32_t namebuf_len; - uint32_t name_len; - uint32_t scope_len = 0; - - if (r == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, - "wrepl_nbt_name NULL pointer"); - } - - if (!(ndr_flags & NDR_SCALARS)) { - return NDR_ERR_SUCCESS; - } - - name_len = strlen(r->name); - if (name_len > 15) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "wrepl_nbt_name longer as 15 chars: %s", - r->name); - } - - if (r->scope) { - scope_len = strlen(r->scope); - } - if (scope_len > 238) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "wrepl_nbt_name scope longer as 238 chars: %s", - r->scope); - } - - namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s", - r->name, 'X', - (r->scope?r->scope:"")); - if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory"); - - namebuf_len = strlen((char *)namebuf) + 1; - - /* - * we need to set the type here, and use a place-holder in the talloc_asprintf() - * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results - */ - namebuf[15] = r->type; - - /* oh wow, what a nasty bug in windows ... */ - if (r->type == 0x1b) { - namebuf[15] = namebuf[0]; - namebuf[0] = 0x1b; - } - - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, namebuf_len)); - NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len)); - - talloc_free(namebuf); - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r) -{ - char *s = nbt_name_string(ndr, r); - ndr_print_string(ndr, name, s); - talloc_free(s); -} - -_PUBLIC_ enum ndr_err_code ndr_push_nbt_res_rec(struct ndr_push *ndr, int ndr_flags, const struct nbt_res_rec *r) -{ - { - uint32_t _flags_save_STRUCT = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX); - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_nbt_name(ndr, NDR_SCALARS, &r->name)); - NDR_CHECK(ndr_push_nbt_qtype(ndr, NDR_SCALARS, r->rr_type)); - NDR_CHECK(ndr_push_nbt_qclass(ndr, NDR_SCALARS, r->rr_class)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ttl)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->rdata, ((((r->rr_type) == NBT_QTYPE_NETBIOS) && ((r->rdata).data.length == 2))?0:r->rr_type))); - NDR_CHECK(ndr_push_nbt_rdata(ndr, NDR_SCALARS, &r->rdata)); - } - if (ndr_flags & NDR_BUFFERS) { - } - ndr->flags = _flags_save_STRUCT; - } - return NDR_ERR_SUCCESS; -} diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c deleted file mode 100644 index 5d4611e2d9..0000000000 --- a/source4/libcli/nbt/nbtsocket.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - low level socket handling for nbt 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 "lib/events/events.h" -#include "lib/util/dlinklist.h" -#include "libcli/nbt/libnbt.h" -#include "lib/socket/socket.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -#define NBT_MAX_REPLIES 1000 - -/* - destroy a pending request -*/ -static int nbt_name_request_destructor(struct nbt_name_request *req) -{ - if (req->state == NBT_REQUEST_SEND) { - DLIST_REMOVE(req->nbtsock->send_queue, req); - } - if (req->state == NBT_REQUEST_WAIT) { - req->nbtsock->num_pending--; - } - if (req->name_trn_id != 0 && !req->is_reply) { - idr_remove(req->nbtsock->idr, req->name_trn_id); - req->name_trn_id = 0; - } - if (req->te) { - talloc_free(req->te); - req->te = NULL; - } - if (req->nbtsock->send_queue == NULL) { - EVENT_FD_NOT_WRITEABLE(req->nbtsock->fde); - } - if (req->nbtsock->num_pending == 0 && - req->nbtsock->incoming.handler == NULL) { - EVENT_FD_NOT_READABLE(req->nbtsock->fde); - } - return 0; -} - - -/* - handle send events on a nbt name socket -*/ -static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) -{ - struct nbt_name_request *req = nbtsock->send_queue; - TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); - NTSTATUS status; - - while ((req = nbtsock->send_queue)) { - size_t len; - - len = req->encoded.length; - status = socket_sendto(nbtsock->sock, &req->encoded, &len, - req->dest); - if (NT_STATUS_IS_ERR(status)) goto failed; - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - DLIST_REMOVE(nbtsock->send_queue, req); - req->state = NBT_REQUEST_WAIT; - if (req->is_reply) { - talloc_free(req); - } else { - EVENT_FD_READABLE(nbtsock->fde); - nbtsock->num_pending++; - } - } - - EVENT_FD_NOT_WRITEABLE(nbtsock->fde); - talloc_free(tmp_ctx); - return; - -failed: - DLIST_REMOVE(nbtsock->send_queue, req); - nbt_name_request_destructor(req); - req->status = status; - req->state = NBT_REQUEST_ERROR; - talloc_free(tmp_ctx); - if (req->async.fn) { - req->async.fn(req); - } else if (req->is_reply) { - talloc_free(req); - } - return; -} - - -/* - handle a request timeout -*/ -static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private) -{ - struct nbt_name_request *req = talloc_get_type(private, - struct nbt_name_request); - - if (req->num_retries != 0) { - req->num_retries--; - req->te = event_add_timed(req->nbtsock->event_ctx, req, - timeval_add(&t, req->timeout, 0), - nbt_name_socket_timeout, req); - if (req->state != NBT_REQUEST_SEND) { - req->state = NBT_REQUEST_SEND; - DLIST_ADD_END(req->nbtsock->send_queue, req, - struct nbt_name_request *); - } - EVENT_FD_WRITEABLE(req->nbtsock->fde); - return; - } - - nbt_name_request_destructor(req); - if (req->num_replies == 0) { - req->state = NBT_REQUEST_TIMEOUT; - req->status = NT_STATUS_IO_TIMEOUT; - } else { - req->state = NBT_REQUEST_DONE; - req->status = NT_STATUS_OK; - } - if (req->async.fn) { - req->async.fn(req); - } else if (req->is_reply) { - talloc_free(req); - } -} - - - -/** - handle recv events on a nbt name socket -*/ -static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) -{ - TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); - NTSTATUS status; - enum ndr_err_code ndr_err; - struct socket_address *src; - DATA_BLOB blob; - size_t nread, dsize; - struct nbt_name_packet *packet; - struct nbt_name_request *req; - - status = socket_pending(nbtsock->sock, &dsize); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - blob = data_blob_talloc(tmp_ctx, NULL, dsize); - if (blob.data == NULL) { - talloc_free(tmp_ctx); - return; - } - - status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, - tmp_ctx, &src); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - packet = talloc(tmp_ctx, struct nbt_name_packet); - if (packet == NULL) { - talloc_free(tmp_ctx); - return; - } - - /* parse the request */ - ndr_err = ndr_pull_struct_blob(&blob, packet, nbtsock->iconv_convenience, packet, - (ndr_pull_flags_fn_t)ndr_pull_nbt_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(2,("Failed to parse incoming NBT name packet - %s\n", - nt_errstr(status))); - talloc_free(tmp_ctx); - return; - } - - if (DEBUGLVL(10)) { - DEBUG(10,("Received nbt packet of length %d from %s:%d\n", - (int)blob.length, src->addr, src->port)); - NDR_PRINT_DEBUG(nbt_name_packet, packet); - } - - /* if its not a reply then pass it off to the incoming request - handler, if any */ - if (!(packet->operation & NBT_FLAG_REPLY)) { - if (nbtsock->incoming.handler) { - nbtsock->incoming.handler(nbtsock, packet, src); - } - talloc_free(tmp_ctx); - return; - } - - /* find the matching request */ - req = (struct nbt_name_request *)idr_find(nbtsock->idr, - packet->name_trn_id); - if (req == NULL) { - if (nbtsock->unexpected.handler) { - nbtsock->unexpected.handler(nbtsock, packet, src); - } else { - DEBUG(10,("Failed to match request for incoming name packet id 0x%04x on %p\n", - packet->name_trn_id, nbtsock)); - } - talloc_free(tmp_ctx); - return; - } - - /* if this is a WACK response, this we need to go back to waiting, - but perhaps increase the timeout */ - if ((packet->operation & NBT_OPCODE) == NBT_OPCODE_WACK) { - if (req->received_wack || packet->ancount < 1) { - nbt_name_request_destructor(req); - req->status = NT_STATUS_INVALID_NETWORK_RESPONSE; - req->state = NBT_REQUEST_ERROR; - goto done; - } - talloc_free(req->te); - /* we know we won't need any more retries - the server - has received our request */ - req->num_retries = 0; - req->received_wack = true; - /* although there can be a timeout in the packet, w2k3 screws it up, - so better to set it ourselves */ - req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30); - req->te = event_add_timed(req->nbtsock->event_ctx, req, - timeval_current_ofs(req->timeout, 0), - nbt_name_socket_timeout, req); - talloc_free(tmp_ctx); - return; - } - - - req->replies = talloc_realloc(req, req->replies, struct nbt_name_reply, req->num_replies+1); - if (req->replies == NULL) { - nbt_name_request_destructor(req); - req->state = NBT_REQUEST_ERROR; - req->status = NT_STATUS_NO_MEMORY; - goto done; - } - - talloc_steal(req, src); - req->replies[req->num_replies].dest = src; - talloc_steal(req, packet); - req->replies[req->num_replies].packet = packet; - req->num_replies++; - - /* if we don't want multiple replies then we are done */ - if (req->allow_multiple_replies && - req->num_replies < NBT_MAX_REPLIES) { - talloc_free(tmp_ctx); - return; - } - - nbt_name_request_destructor(req); - req->state = NBT_REQUEST_DONE; - req->status = NT_STATUS_OK; - -done: - talloc_free(tmp_ctx); - if (req->async.fn) { - req->async.fn(req); - } -} - -/* - handle fd events on a nbt_name_socket -*/ -static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) -{ - struct nbt_name_socket *nbtsock = talloc_get_type(private, - struct nbt_name_socket); - if (flags & EVENT_FD_WRITE) { - nbt_name_socket_send(nbtsock); - } - if (flags & EVENT_FD_READ) { - nbt_name_socket_recv(nbtsock); - } -} - - -/* - initialise a nbt_name_socket. The event_ctx is optional, if provided - then operations will use that event context -*/ -_PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, - struct event_context *event_ctx, - struct smb_iconv_convenience *iconv_convenience) -{ - struct nbt_name_socket *nbtsock; - NTSTATUS status; - - nbtsock = talloc(mem_ctx, struct nbt_name_socket); - if (nbtsock == NULL) goto failed; - - 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); - if (!NT_STATUS_IS_OK(status)) goto failed; - - socket_set_option(nbtsock->sock, "SO_BROADCAST", "1"); - - talloc_steal(nbtsock, nbtsock->sock); - - nbtsock->idr = idr_init(nbtsock); - if (nbtsock->idr == NULL) goto failed; - - nbtsock->send_queue = NULL; - nbtsock->num_pending = 0; - nbtsock->incoming.handler = NULL; - nbtsock->unexpected.handler = NULL; - nbtsock->iconv_convenience = iconv_convenience; - - nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock, - socket_get_fd(nbtsock->sock), 0, - nbt_name_socket_handler, nbtsock); - - return nbtsock; - -failed: - talloc_free(nbtsock); - return NULL; -} - -/* - send off a nbt name request -*/ -struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request, - int timeout, int retries, - bool allow_multiple_replies) -{ - struct nbt_name_request *req; - int id; - enum ndr_err_code ndr_err; - - req = talloc_zero(nbtsock, struct nbt_name_request); - if (req == NULL) goto failed; - - req->nbtsock = nbtsock; - req->allow_multiple_replies = allow_multiple_replies; - req->state = NBT_REQUEST_SEND; - req->is_reply = false; - req->timeout = timeout; - req->num_retries = retries; - req->dest = dest; - if (talloc_reference(req, dest) == NULL) goto failed; - - /* we select a random transaction id unless the user supplied one */ - if (request->name_trn_id == 0) { - id = idr_get_new_random(req->nbtsock->idr, req, UINT16_MAX); - } else { - if (idr_find(req->nbtsock->idr, request->name_trn_id)) goto failed; - id = idr_get_new_above(req->nbtsock->idr, req, request->name_trn_id, - UINT16_MAX); - } - if (id == -1) goto failed; - - request->name_trn_id = id; - req->name_trn_id = id; - - req->te = event_add_timed(nbtsock->event_ctx, req, - timeval_current_ofs(req->timeout, 0), - nbt_name_socket_timeout, req); - - talloc_set_destructor(req, nbt_name_request_destructor); - - ndr_err = ndr_push_struct_blob(&req->encoded, req, - req->nbtsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) goto failed; - - DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); - - if (DEBUGLVL(10)) { - DEBUG(10,("Queueing nbt packet to %s:%d\n", - req->dest->addr, req->dest->port)); - NDR_PRINT_DEBUG(nbt_name_packet, request); - } - - EVENT_FD_WRITEABLE(nbtsock->fde); - - return req; - -failed: - talloc_free(req); - return NULL; -} - - -/* - send off a nbt name reply -*/ -_PUBLIC_ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - struct socket_address *dest, - struct nbt_name_packet *request) -{ - struct nbt_name_request *req; - enum ndr_err_code ndr_err; - - req = talloc_zero(nbtsock, struct nbt_name_request); - NT_STATUS_HAVE_NO_MEMORY(req); - - req->nbtsock = nbtsock; - req->dest = dest; - if (talloc_reference(req, dest) == NULL) goto failed; - req->state = NBT_REQUEST_SEND; - req->is_reply = true; - - talloc_set_destructor(req, nbt_name_request_destructor); - - if (DEBUGLVL(10)) { - NDR_PRINT_DEBUG(nbt_name_packet, request); - } - - ndr_err = ndr_push_struct_blob(&req->encoded, req, - req->nbtsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(req); - return ndr_map_error2ntstatus(ndr_err); - } - - DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); - - EVENT_FD_WRITEABLE(nbtsock->fde); - - return NT_STATUS_OK; - -failed: - talloc_free(req); - return NT_STATUS_NO_MEMORY; -} - -/* - wait for a nbt request to complete -*/ -NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) -{ - if (!req) return NT_STATUS_NO_MEMORY; - - while (req->state < NBT_REQUEST_DONE) { - if (event_loop_once(req->nbtsock->event_ctx) != 0) { - req->state = NBT_REQUEST_ERROR; - req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; - break; - } - } - return req->status; -} - - -/* - setup a handler for incoming requests -*/ -_PUBLIC_ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, - void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - struct socket_address *), - void *private) -{ - nbtsock->incoming.handler = handler; - nbtsock->incoming.private = private; - EVENT_FD_READABLE(nbtsock->fde); - return NT_STATUS_OK; -} - - -/* - turn a NBT rcode into a NTSTATUS -*/ -_PUBLIC_ NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode) -{ - int i; - struct { - enum nbt_rcode rcode; - NTSTATUS status; - } map[] = { - { NBT_RCODE_FMT, NT_STATUS_INVALID_PARAMETER }, - { NBT_RCODE_SVR, NT_STATUS_SERVER_DISABLED }, - { NBT_RCODE_NAM, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { NBT_RCODE_IMP, NT_STATUS_NOT_SUPPORTED }, - { NBT_RCODE_RFS, NT_STATUS_ACCESS_DENIED }, - { NBT_RCODE_ACT, NT_STATUS_ADDRESS_ALREADY_EXISTS }, - { NBT_RCODE_CFT, NT_STATUS_CONFLICTING_ADDRESSES } - }; - for (i=0;i<ARRAY_SIZE(map);i++) { - if (map[i].rcode == rcode) { - return map[i].status; - } - } - return NT_STATUS_UNSUCCESSFUL; -} diff --git a/source4/libcli/nbt/pynbt.c b/source4/libcli/nbt/pynbt.c deleted file mode 100644 index e91096630a..0000000000 --- a/source4/libcli/nbt/pynbt.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright © Jelmer Vernooij <jelmer@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 <Python.h> -#include "libcli/util/pyerrors.h" -#include "libcli/nbt/libnbt.h" -#include "lib/events/events.h" -#include "param/param.h" - -PyAPI_DATA(PyTypeObject) nbt_node_Type; - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct nbt_name_socket *socket; -} nbt_node_Object; - -static void py_nbt_node_dealloc(PyObject *obj) -{ - talloc_free(((nbt_node_Object *)obj)->mem_ctx); - PyObject_Del(obj); -} - -static PyObject *py_nbt_node_init(PyTypeObject *self, PyObject *args, PyObject *kwargs) -{ - struct event_context *ev; - nbt_node_Object *ret = PyObject_New(nbt_node_Object, &nbt_node_Type); - - ret->mem_ctx = talloc_new(NULL); - if (ret->mem_ctx == NULL) - return NULL; - - ev = s4_event_context_init(ret->mem_ctx); - ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, lp_iconv_convenience(global_loadparm)); - return (PyObject *)ret; -} - -static bool PyObject_AsDestinationTuple(PyObject *obj, const char **dest_addr, uint16_t *dest_port) -{ - if (PyString_Check(obj)) { - *dest_addr = PyString_AsString(obj); - *dest_port = NBT_NAME_SERVICE_PORT; - return true; - } - - if (PyTuple_Check(obj)) { - if (PyTuple_Size(obj) < 1) { - PyErr_SetString(PyExc_TypeError, "Destination tuple size invalid"); - return false; - } - - if (!PyString_Check(PyTuple_GetItem(obj, 0))) { - PyErr_SetString(PyExc_TypeError, "Destination tuple first element not string"); - return false; - } - - *dest_addr = PyString_AsString(obj); - - if (PyTuple_Size(obj) == 1) { - *dest_port = NBT_NAME_SERVICE_PORT; - return true; - } else if (PyInt_Check(PyTuple_GetItem(obj, 1))) { - *dest_port = PyInt_AsLong(PyTuple_GetItem(obj, 1)); - return true; - } else { - PyErr_SetString(PyExc_TypeError, "Destination tuple second element not a port"); - return false; - } - } - - PyErr_SetString(PyExc_TypeError, "Destination tuple second element not a port"); - return false; -} - -static bool PyObject_AsNBTName(PyObject *obj, struct nbt_name_socket *socket, struct nbt_name *name) -{ - if (PyTuple_Check(obj)) { - if (PyTuple_Size(obj) == 2) { - name->name = PyString_AsString(PyTuple_GetItem(obj, 0)); - name->type = PyInt_AsLong(PyTuple_GetItem(obj, 1)); - name->scope = NULL; - return true; - } else if (PyTuple_Size(obj) == 3) { - name->name = PyString_AsString(PyTuple_GetItem(obj, 0)); - name->scope = PyString_AsString(PyTuple_GetItem(obj, 1)); - name->type = PyInt_AsLong(PyTuple_GetItem(obj, 2)); - return true; - } else { - PyErr_SetString(PyExc_TypeError, "Invalid tuple size"); - return false; - } - } - - if (PyString_Check(obj)) { - /* FIXME: Parse string to be able to interpret things like RHONWYN<02> ? */ - name->name = PyString_AsString(obj); - name->scope = NULL; - name->type = 0; - return true; - } - - PyErr_SetString(PyExc_TypeError, "Invalid type for object"); - return false; -} - -static PyObject *PyObject_FromNBTName(struct nbt_name_socket *socket, struct smb_iconv_convenience *ic, - struct nbt_name *name) -{ - if (name->scope) { - return Py_BuildValue("(ssi)", name->name, name->scope, name->type); - } else { - return Py_BuildValue("(si)", name->name, name->type); - } -} - -static PyObject *py_nbt_name_query(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *reply_addrs, *py_dest, *py_name; - struct nbt_name_query io; - NTSTATUS status; - int i; - - const char *kwnames[] = { "name", "dest", "broadcast", "wins", "timeout", - "retries", NULL }; - io.in.broadcast = true; - io.in.wins_lookup = false; - io.in.timeout = 0; - io.in.retries = 3; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bbii:query_name", - discard_const_p(char *, kwnames), - &py_name, &py_dest, - &io.in.broadcast, &io.in.wins_lookup, - &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_query(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - reply_addrs = PyList_New(io.out.num_addrs); - if (reply_addrs == NULL) { - Py_DECREF(ret); - return NULL; - } - - for (i = 0; i < io.out.num_addrs; i++) { - PyList_SetItem(reply_addrs, i, PyString_FromString(io.out.reply_addrs[i])); - } - - PyTuple_SetItem(ret, 2, reply_addrs); - return ret; -} - -static PyObject *py_nbt_name_status(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *py_dest, *py_name, *py_names; - struct nbt_name_status io; - int i; - NTSTATUS status; - - const char *kwnames[] = { "name", "dest", "timeout", "retries", NULL }; - - io.in.timeout = 0; - io.in.retries = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ii:name_status", - discard_const_p(char *, kwnames), - &py_name, &py_dest, - &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_status(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - py_names = PyList_New(io.out.status.num_names); - - for (i = 0; i < io.out.status.num_names; i++) { - PyList_SetItem(py_names, i, Py_BuildValue("(sii)", - io.out.status.names[i].name, - io.out.status.names[i].nb_flags, - io.out.status.names[i].type)); - } - - PyTuple_SetItem(ret, 2, py_names); - - return ret; -} - -static PyObject *py_nbt_name_register(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *py_dest, *py_name; - struct nbt_name_register io; - NTSTATUS status; - - const char *kwnames[] = { "name", "address", "dest", "register_demand", "broadcast", - "multi_homed", "ttl", "timeout", "retries", NULL }; - - io.in.broadcast = true; - io.in.multi_homed = true; - io.in.register_demand = true; - io.in.timeout = 0; - io.in.retries = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|bbbiii:query_name", - discard_const_p(char *, kwnames), - &py_name, &io.in.address, &py_dest, - &io.in.register_demand, - &io.in.broadcast, &io.in.multi_homed, - &io.in.ttl, &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_register(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - PyTuple_SetItem(ret, 2, PyString_FromString(io.out.reply_addr)); - - PyTuple_SetItem(ret, 3, PyInt_FromLong(io.out.rcode)); - - return ret; -} - -static PyObject *py_nbt_name_refresh(PyObject *self, PyObject *args, PyObject *kwargs) -{ - nbt_node_Object *node = (nbt_node_Object *)self; - PyObject *ret, *py_dest, *py_name; - struct nbt_name_refresh io; - NTSTATUS status; - - const char *kwnames[] = { "name", "address", "dest", "nb_flags", "broadcast", - "ttl", "timeout", "retries", NULL }; - - io.in.broadcast = true; - io.in.nb_flags = 0; - io.in.timeout = 0; - io.in.retries = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|ibiii:query_name", - discard_const_p(char *, kwnames), - &py_name, &io.in.address, &py_dest, - &io.in.nb_flags, - &io.in.broadcast, - &io.in.ttl, &io.in.timeout, &io.in.retries)) { - return NULL; - } - - if (!PyObject_AsDestinationTuple(py_dest, &io.in.dest_addr, &io.in.dest_port)) - return NULL; - - if (!PyObject_AsNBTName(py_name, node->socket, &io.in.name)) - return NULL; - - status = nbt_name_refresh(node->socket, NULL, &io); - - if (NT_STATUS_IS_ERR(status)) { - PyErr_SetNTSTATUS(status); - return NULL; - } - - ret = PyTuple_New(3); - if (ret == NULL) - return NULL; - PyTuple_SetItem(ret, 0, PyString_FromString(io.out.reply_from)); - - py_name = PyObject_FromNBTName(node->socket, lp_iconv_convenience(global_loadparm), &io.out.name); - if (py_name == NULL) - return NULL; - - PyTuple_SetItem(ret, 1, py_name); - - PyTuple_SetItem(ret, 2, PyString_FromString(io.out.reply_addr)); - - PyTuple_SetItem(ret, 3, PyInt_FromLong(io.out.rcode)); - - return ret; -} - -static PyObject *py_nbt_name_release(PyObject *self, PyObject *args, PyObject *kwargs) -{ - return Py_None; /* FIXME */ -} - -static PyMethodDef py_nbt_methods[] = { - { "query_name", (PyCFunction)py_nbt_name_query, METH_VARARGS|METH_KEYWORDS, - "S.query_name(name, dest, broadcast=True, wins=False, timeout=0, retries=3) -> (reply_from, name, reply_addr)\n" - "Query for a NetBIOS name" }, - { "register_name", (PyCFunction)py_nbt_name_register, METH_VARARGS|METH_KEYWORDS, - "S.register_name(name, address, dest, register_demand=True, broadcast=True, multi_homed=True, ttl=0, timeout=0, retries=0) -> (reply_from, name, reply_addr, rcode)\n" - "Register a new name" }, - { "release_name", (PyCFunction)py_nbt_name_release, METH_VARARGS|METH_KEYWORDS, "S.release_name(name, address, dest, nb_flags=0, broadcast=true, timeout=0, retries=3) -> (reply_from, name, reply_addr, rcode)\n" - "release a previously registered name" }, - { "refresh_name", (PyCFunction)py_nbt_name_refresh, METH_VARARGS|METH_KEYWORDS, "S.refresh_name(name, address, dest, nb_flags=0, broadcast=True, ttl=0, timeout=0, retries=0) -> (reply_from, name, reply_addr, rcode)\n" - "release a previously registered name" }, - { "name_status", (PyCFunction)py_nbt_name_status, METH_VARARGS|METH_KEYWORDS, - "S.name_status(name, dest, timeout=0, retries=0) -> (reply_from, name, status)\n" - "Find the status of a name" }, - - { NULL } -}; - -PyTypeObject nbt_node_Type = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "netbios.Node", - .tp_basicsize = sizeof(nbt_node_Object), - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, - .tp_new = py_nbt_node_init, - .tp_dealloc = py_nbt_node_dealloc, - .tp_methods = py_nbt_methods, - .tp_doc = "Node()\n" - "Create a new NetBIOS node\n" -}; - -void initnetbios(void) -{ - PyObject *mod; - if (PyType_Ready(&nbt_node_Type) < 0) - return; - - mod = Py_InitModule3("netbios", NULL, "NetBIOS over TCP/IP support"); - - Py_INCREF((PyObject *)&nbt_node_Type); - PyModule_AddObject(mod, "Node", (PyObject *)&nbt_node_Type); -} diff --git a/source4/libcli/nbt/tools/nmblookup.c b/source4/libcli/nbt/tools/nmblookup.c new file mode 100644 index 0000000000..0d98cb99de --- /dev/null +++ b/source4/libcli/nbt/tools/nmblookup.c @@ -0,0 +1,381 @@ +/* + Unix SMB/CIFS implementation. + + NBT client - used to lookup netbios names + + Copyright (C) Andrew Tridgell 1994-2005 + Copyright (C) Jelmer Vernooij 2003 (Conversion to popt) + + 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 "lib/cmdline/popt_common.h" +#include "lib/socket/socket.h" +#include "lib/events/events.h" +#include "system/network.h" +#include "system/locale.h" +#include "lib/socket/netif.h" +#include "librpc/gen_ndr/nbt.h" +#include "../libcli/nbt/libnbt.h" +#include "param/param.h" + +/* command line options */ +static struct { + const char *broadcast_address; + const char *unicast_address; + bool find_master; + bool wins_lookup; + bool node_status; + bool root_port; + bool lookup_by_ip; + bool case_sensitive; +} options; + +/* + clean any binary from a node name +*/ +static const char *clean_name(TALLOC_CTX *mem_ctx, const char *name) +{ + char *ret = talloc_strdup(mem_ctx, name); + int i; + for (i=0;ret[i];i++) { + if (!isprint((unsigned char)ret[i])) ret[i] = '.'; + } + return ret; +} + +/* + turn a node status flags field into a string +*/ +static char *node_status_flags(TALLOC_CTX *mem_ctx, uint16_t flags) +{ + char *ret; + const char *group = " "; + const char *type = "B"; + + if (flags & NBT_NM_GROUP) { + group = "<GROUP>"; + } + + switch (flags & NBT_NM_OWNER_TYPE) { + case NBT_NODE_B: + type = "B"; + break; + case NBT_NODE_P: + type = "P"; + break; + case NBT_NODE_M: + type = "M"; + break; + case NBT_NODE_H: + type = "H"; + break; + } + + ret = talloc_asprintf(mem_ctx, "%s %s", group, type); + + if (flags & NBT_NM_DEREGISTER) { + ret = talloc_asprintf_append_buffer(ret, " <DEREGISTERING>"); + } + if (flags & NBT_NM_CONFLICT) { + ret = talloc_asprintf_append_buffer(ret, " <CONFLICT>"); + } + if (flags & NBT_NM_ACTIVE) { + ret = talloc_asprintf_append_buffer(ret, " <ACTIVE>"); + } + if (flags & NBT_NM_PERMANENT) { + ret = talloc_asprintf_append_buffer(ret, " <PERMANENT>"); + } + + return ret; +} + +/* do a single node status */ +static bool do_node_status(struct nbt_name_socket *nbtsock, + const char *addr, uint16_t port) +{ + struct nbt_name_status io; + NTSTATUS status; + + io.in.name.name = "*"; + io.in.name.type = NBT_NAME_CLIENT; + io.in.name.scope = NULL; + io.in.dest_addr = addr; + io.in.dest_port = port; + io.in.timeout = 1; + io.in.retries = 2; + + status = nbt_name_status(nbtsock, nbtsock, &io); + if (NT_STATUS_IS_OK(status)) { + int i; + printf("Node status reply from %s\n", + io.out.reply_from); + for (i=0;i<io.out.status.num_names;i++) { + d_printf("\t%-16s <%02x> %s\n", + clean_name(nbtsock, io.out.status.names[i].name), + io.out.status.names[i].type, + node_status_flags(nbtsock, io.out.status.names[i].nb_flags)); + } + printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n", + io.out.status.statistics.unit_id[0], + io.out.status.statistics.unit_id[1], + io.out.status.statistics.unit_id[2], + io.out.status.statistics.unit_id[3], + io.out.status.statistics.unit_id[4], + io.out.status.statistics.unit_id[5]); + return true; + } + + return false; +} + +/* do a single node query */ +static NTSTATUS do_node_query(struct nbt_name_socket *nbtsock, + const char *addr, + uint16_t port, + const char *node_name, + enum nbt_name_type node_type, + bool broadcast) +{ + struct nbt_name_query io; + NTSTATUS status; + int i; + + io.in.name.name = node_name; + io.in.name.type = node_type; + io.in.name.scope = NULL; + io.in.dest_addr = addr; + io.in.dest_port = port; + io.in.broadcast = broadcast; + io.in.wins_lookup = options.wins_lookup; + io.in.timeout = 1; + io.in.retries = 2; + + status = nbt_name_query(nbtsock, nbtsock, &io); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0;i<io.out.num_addrs;i++) { + printf("%s %s<%02x>\n", + io.out.reply_addrs[i], + io.out.name.name, + io.out.name.type); + } + if (options.node_status && io.out.num_addrs > 0) { + do_node_status(nbtsock, io.out.reply_addrs[0], port); + } + + return status; +} + + +static bool process_one(struct loadparm_context *lp_ctx, struct event_context *ev, + struct interface *ifaces, const char *name, int nbt_port) +{ + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + enum nbt_name_type node_type = NBT_NAME_CLIENT; + char *node_name, *p; + struct socket_address *all_zero_addr; + struct nbt_name_socket *nbtsock; + NTSTATUS status = NT_STATUS_OK; + bool ret = true; + + if (!options.case_sensitive) { + name = strupper_talloc(tmp_ctx, name); + } + + if (options.find_master) { + node_type = NBT_NAME_MASTER; + if (*name == '-' || *name == '_') { + name = "\01\02__MSBROWSE__\02"; + node_type = NBT_NAME_MS; + } + } + + p = strchr(name, '#'); + if (p) { + node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name)); + node_type = (enum nbt_name_type)strtol(p+1, NULL, 16); + } else { + node_name = talloc_strdup(tmp_ctx, name); + } + + nbtsock = nbt_name_socket_init(tmp_ctx, ev, lp_iconv_convenience(lp_ctx)); + + if (options.root_port) { + all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, + "0.0.0.0", NBT_NAME_SERVICE_PORT); + + if (!all_zero_addr) { + talloc_free(tmp_ctx); + return false; + } + + status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to bind to local port 137 - %s\n", nt_errstr(status)); + talloc_free(tmp_ctx); + return false; + } + } + + if (options.lookup_by_ip) { + ret = do_node_status(nbtsock, name, nbt_port); + talloc_free(tmp_ctx); + return ret; + } + + if (options.broadcast_address) { + status = do_node_query(nbtsock, options.broadcast_address, nbt_port, + node_name, node_type, true); + } else if (options.unicast_address) { + status = do_node_query(nbtsock, options.unicast_address, + nbt_port, node_name, node_type, false); + } else { + int i, num_interfaces; + + num_interfaces = iface_count(ifaces); + for (i=0;i<num_interfaces;i++) { + const char *bcast = iface_n_bcast(ifaces, i); + if (bcast == NULL) continue; + status = do_node_query(nbtsock, bcast, nbt_port, + node_name, node_type, true); + if (NT_STATUS_IS_OK(status)) break; + } + } + + if (!NT_STATUS_IS_OK(status)) { + printf("Lookup failed - %s\n", nt_errstr(status)); + ret = false; + } + + talloc_free(tmp_ctx); + return ret; +} + +/* + main program +*/ +int main(int argc, const char *argv[]) +{ + bool ret = true; + struct interface *ifaces; + struct event_context *ev; + poptContext pc; + int opt; + enum { + OPT_BROADCAST_ADDRESS = 1000, + OPT_UNICAST_ADDRESS, + OPT_FIND_MASTER, + OPT_WINS_LOOKUP, + OPT_NODE_STATUS, + OPT_ROOT_PORT, + OPT_LOOKUP_BY_IP, + OPT_CASE_SENSITIVE + }; + struct poptOption long_options[] = { + POPT_AUTOHELP + { "broadcast", 'B', POPT_ARG_STRING, NULL, OPT_BROADCAST_ADDRESS, + "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, + + { "unicast", 'U', POPT_ARG_STRING, NULL, OPT_UNICAST_ADDRESS, + "Specify address to use for unicast", NULL }, + + { "master-browser", 'M', POPT_ARG_NONE, NULL, OPT_FIND_MASTER, + "Search for a master browser", NULL }, + + { "wins", 'W', POPT_ARG_NONE, NULL, OPT_WINS_LOOKUP, + "Do a WINS lookup", NULL }, + + { "status", 'S', POPT_ARG_NONE, NULL, OPT_NODE_STATUS, + "Lookup node status as well", NULL }, + + { "root-port", 'r', POPT_ARG_NONE, NULL, OPT_ROOT_PORT, + "Use root port 137 (Win95 only replies to this)", NULL }, + + { "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, OPT_LOOKUP_BY_IP, + "Do a node status on <name> as an IP Address", NULL }, + + { "case-sensitive", 0, POPT_ARG_NONE, NULL, OPT_CASE_SENSITIVE, + "Don't uppercase the name before sending", NULL }, + + POPT_COMMON_SAMBA + { 0, 0, 0, 0 } + }; + + pc = poptGetContext("nmblookup", argc, argv, long_options, + POPT_CONTEXT_KEEP_FIRST); + + poptSetOtherOptionHelp(pc, "<NODE> ..."); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + case OPT_BROADCAST_ADDRESS: + options.broadcast_address = poptGetOptArg(pc); + break; + case OPT_UNICAST_ADDRESS: + options.unicast_address = poptGetOptArg(pc); + break; + case OPT_FIND_MASTER: + options.find_master = true; + break; + case OPT_WINS_LOOKUP: + options.wins_lookup = true; + break; + case OPT_NODE_STATUS: + options.node_status = true; + break; + case OPT_ROOT_PORT: + options.root_port = true; + break; + case OPT_LOOKUP_BY_IP: + options.lookup_by_ip = true; + break; + case OPT_CASE_SENSITIVE: + options.case_sensitive = true; + break; + } + } + + /* swallow argv[0] */ + poptGetArg(pc); + + if(!poptPeekArg(pc)) { + poptPrintUsage(pc, stderr, 0); + exit(1); + } + + load_interfaces(NULL, lp_interfaces(cmdline_lp_ctx), &ifaces); + + ev = s4_event_context_init(talloc_autofree_context()); + + while (poptPeekArg(pc)) { + const char *name = poptGetArg(pc); + + ret &= process_one(cmdline_lp_ctx, ev, ifaces, name, lp_nbt_port(cmdline_lp_ctx)); + } + + talloc_free(ev); + + talloc_free(ifaces); + + poptFreeContext(pc); + + if (!ret) { + return 1; + } + + return 0; +} diff --git a/source4/libcli/ndr_netlogon.c b/source4/libcli/ndr_netlogon.c deleted file mode 100644 index 504b3b02a7..0000000000 --- a/source4/libcli/ndr_netlogon.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - 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 deleted file mode 100644 index 052d7cbc1e..0000000000 --- a/source4/libcli/netlogon.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - 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 deleted file mode 100644 index 177ed3a514..0000000000 --- a/source4/libcli/netlogon.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - 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/clisession.c b/source4/libcli/raw/clisession.c index ad4ca7b471..38d8f700f2 100644 --- a/source4/libcli/raw/clisession.c +++ b/source4/libcli/raw/clisession.c @@ -35,7 +35,8 @@ Initialize the session context ****************************************************************************/ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, - TALLOC_CTX *parent_ctx, bool primary) + TALLOC_CTX *parent_ctx, bool primary, + struct smbcli_session_options options) { struct smbcli_session *session; uint16_t flags2; @@ -53,9 +54,7 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport, } session->pid = (uint16_t)getpid(); session->vuid = UID_FIELD_INVALID; - session->options.lanman_auth = lp_client_lanman_auth(global_loadparm); - session->options.ntlmv2_auth = lp_client_ntlmv2_auth(global_loadparm); - session->options.plaintext_auth = lp_client_plaintext_auth(global_loadparm); + session->options = options; capabilities = transport->negotiate.capabilities; diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index e95ae3271e..f8ef343e3a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -28,7 +28,7 @@ #include "lib/stream/packet.h" #include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" /* diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 15cd70833c..4b5d2dc397 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -177,7 +177,8 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, struct event_context *ev, - struct smbcli_options *options) + struct smbcli_options *options, + struct smbcli_session_options *session_options) { struct smb_composite_connect io; NTSTATUS status; @@ -200,6 +201,7 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, * is complete -- abartlet 2008-04-28 */ io.in.workgroup = lp_workgroup(global_loadparm); io.in.options = *options; + io.in.session_options = *session_options; status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 537041c137..c2269cbbc2 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -904,6 +904,7 @@ enum smb_setfileinfo_level { RAW_SFILEINFO_UNIX_HLINK = SMB_SFILEINFO_UNIX_HLINK, RAW_SFILEINFO_BASIC_INFORMATION = SMB_SFILEINFO_BASIC_INFORMATION, RAW_SFILEINFO_RENAME_INFORMATION = SMB_SFILEINFO_RENAME_INFORMATION, + RAW_SFILEINFO_LINK_INFORMATION = SMB_SFILEINFO_LINK_INFORMATION, RAW_SFILEINFO_DISPOSITION_INFORMATION = SMB_SFILEINFO_DISPOSITION_INFORMATION, RAW_SFILEINFO_POSITION_INFORMATION = SMB_SFILEINFO_POSITION_INFORMATION, RAW_SFILEINFO_FULL_EA_INFORMATION = SMB_SFILEINFO_FULL_EA_INFORMATION, @@ -984,6 +985,7 @@ union smb_setfileinfo { NTTIME write_time; NTTIME change_time; uint32_t attrib; + uint32_t reserved; } in; } basic_info; @@ -1029,6 +1031,17 @@ union smb_setfileinfo { } in; } rename_information; + /* RAW_SFILEINFO_LINK_INFORMATION interface */ + struct { + enum smb_setfileinfo_level level; + struct { + union smb_handle_or_path file; + uint8_t overwrite; + uint64_t root_fid; + const char *new_name; + } in; + } link_information; + /* RAW_SFILEINFO_POSITION_INFORMATION interface */ struct { enum smb_setfileinfo_level level; @@ -1112,6 +1125,15 @@ union smb_setfileinfo { struct security_descriptor *sd; } in; } set_secdesc; + + /* RAW_SFILEINFO_FULL_EA_INFORMATION */ + struct { + enum smb_setfileinfo_level level; + struct { + union smb_handle_or_path file; + struct smb_ea_list eas; + } in; + } full_ea_information; }; diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index d55b4cc42c..bd9bda0db1 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -261,6 +261,12 @@ struct smbcli_request { counter by one */ uint_t sign_single_increment:1; + /* the caller wants to do the signing check */ + bool sign_caller_checks; + + /* give the caller a chance to prevent the talloc_free() in the _recv() function */ + bool do_not_free; + /* the mid of this packet - used to match replies */ uint16_t mid; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index a0e6452748..dd9b1f3e96 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -72,7 +72,11 @@ _PUBLIC_ NTSTATUS smbcli_request_destroy(struct smbcli_request *req) } status = req->status; - talloc_free(req); + + if (!req->do_not_free) { + talloc_free(req); + } + return status; } diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c index 5a4706778a..f7dfb933f1 100644 --- a/source4/libcli/raw/rawsetfileinfo.c +++ b/source4/libcli/raw/rawsetfileinfo.c @@ -37,7 +37,7 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, #define NEED_BLOB(n) do { \ *blob = data_blob_talloc(mem_ctx, NULL, n); \ - if (blob->data == NULL) return false; \ + if (blob->data == NULL && n != 0) return false; \ } while (0) switch (level) { @@ -109,6 +109,16 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx, return true; } + case RAW_SFILEINFO_FULL_EA_INFORMATION: + printf("num_eas=%d\n", parms->full_ea_information.in.eas.num_eas); + NEED_BLOB(ea_list_size_chained( + parms->full_ea_information.in.eas.num_eas, + parms->full_ea_information.in.eas.eas, 4)); + ea_put_list_chained(blob->data, + parms->full_ea_information.in.eas.num_eas, + parms->full_ea_information.in.eas.eas, 4); + return true; + /* Unhandled levels */ case RAW_SFILEINFO_PIPE_INFORMATION: case RAW_SFILEINFO_VALID_DATA_INFORMATION: diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c index 1d03686d9a..e798f052ba 100644 --- a/source4/libcli/raw/smb_signing.c +++ b/source4/libcli/raw/smb_signing.c @@ -23,7 +23,7 @@ #include "smb.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" -#include "lib/crypto/crypto.h" +#include "../lib/crypto/crypto.h" #include "param/param.h" /*********************************************************** @@ -298,11 +298,20 @@ bool smbcli_request_check_sign_mac(struct smbcli_request *req) { bool good; + if (!req->transport->negotiate.sign_info.doing_signing && + req->sign_caller_checks) { + return true; + } + + req->sign_caller_checks = false; + switch (req->transport->negotiate.sign_info.signing_state) { case SMB_SIGNING_ENGINE_OFF: return true; case SMB_SIGNING_ENGINE_BSRSPYL: + return true; + case SMB_SIGNING_ENGINE_ON: { if (req->in.size < (HDR_SS_FIELD + 8)) { @@ -350,6 +359,7 @@ bool smbcli_simple_set_signing(TALLOC_CTX *mem_ctx, dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length); sign_info->signing_state = SMB_SIGNING_ENGINE_ON; + sign_info->next_seq_num = 2; return true; } diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 2e2eb05397..ca78a2ce43 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -75,7 +75,13 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, NTSTATUS resolve_name_bcast_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, const char **reply_addr) { - return resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); + NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, reply_addr); + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + /* this makes much more sense for a bcast name resolution + timeout */ + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return status; } /* diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 8f085c5404..7dafd130f8 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -28,7 +28,7 @@ #include "system/network.h" #include "lib/socket/netif.h" #include "librpc/gen_ndr/ndr_nbt.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" #include "param/param.h" struct nbtlist_state { @@ -46,7 +46,7 @@ struct nbtlist_state { */ static void nbtlist_handler(struct nbt_name_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 nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state); struct nbt_name_query *q; @@ -169,7 +169,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state->queries[i], c)) return c; state->queries[i]->async.fn = nbtlist_handler; - state->queries[i]->async.private = c; + state->queries[i]->async.private_data = c; } return c; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index d89b50e430..dbc4a2ede7 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -165,6 +165,10 @@ struct composite_context *resolve_name_send(struct resolve_context *ctx, } state->method = ctx->methods; + if (state->method == NULL) { + composite_error(c, NT_STATUS_BAD_NETWORK_NAME); + return c; + } state->creq = setup_next_method(c); if (composite_nomem(state->creq, c)) return c; diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 79b91dc836..22de146c99 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -22,7 +22,7 @@ #ifndef __RESOLVE_H__ #define __RESOLVE_H__ -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, struct nbt_name *); typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *, TALLOC_CTX *, const char **); #include "libcli/resolve/proto.h" diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index 3ec180f332..ebce9b98bd 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "libcli/nbt/libnbt.h" +#include "../libcli/nbt/libnbt.h" #include "libcli/resolve/resolve.h" #include "param/param.h" #include "lib/socket/netif.h" diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c index e2ede05545..d5a0a13445 100644 --- a/source4/libcli/security/access_check.c +++ b/source4/libcli/security/access_check.c @@ -38,6 +38,10 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, granted |= SEC_STD_DELETE; } + if (sd->dacl == NULL) { + return granted & ~denied; + } + for (i = 0;i<sd->dacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; @@ -101,10 +105,14 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, return NT_STATUS_OK; } - /* empty dacl denies access */ +#if 0 + /* tridge: previously we had empty dacl denying access, but + that can lead to undeletable directories, where + nobody can change the ACL on a directory */ if (sd->dacl == NULL || sd->dacl->num_aces == 0) { return NT_STATUS_ACCESS_DENIED; } +#endif /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */ if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) && @@ -116,6 +124,10 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, bits_remaining &= ~SEC_STD_DELETE; } + if (sd->dacl == NULL) { + goto done; + } + /* check each ace in turn. */ for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; @@ -143,6 +155,7 @@ NTSTATUS sec_access_check(const struct security_descriptor *sd, } } +done: if (bits_remaining != 0) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/libcli/security/security.i b/source4/libcli/security/security.i index 1d964cc3d5..420439d147 100644 --- a/source4/libcli/security/security.i +++ b/source4/libcli/security/security.i @@ -27,8 +27,8 @@ typedef struct security_token security_token; typedef struct security_descriptor security_descriptor; %} -%import "../../lib/talloc/talloc.i" -%import "../util/errors.i" +%import "../lib/talloc/talloc.i" +%include "../util/errors.i" %import "stdint.i" enum sec_privilege { @@ -105,6 +105,12 @@ typedef struct security_descriptor { %talloctype(dom_sid); typedef struct dom_sid { + %immutable; + uint8_t sid_rev_num; + int8_t num_auths;/* [range(0,15)] */ + uint8_t id_auth[6]; + uint32_t *sub_auths; + %mutable; %extend { dom_sid(TALLOC_CTX *mem_ctx, const char *text) { return dom_sid_parse_talloc(mem_ctx, text); @@ -117,6 +123,10 @@ typedef struct dom_sid { #endif bool equal(const struct dom_sid *other); } +%pythoncode { + def __repr__(self): + return "Sid(%r)" % str(self) +} } dom_sid; %feature("docstring") random_sid "random_sid() -> sid\n" \ diff --git a/source4/libcli/security/security.py b/source4/libcli/security/security.py index 065c7a19e4..8afb3eda61 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.35 +# Version 1.3.36 # # Don't modify this file, modify the SWIG interface instead. @@ -147,8 +147,15 @@ security_descriptor_swigregister(security_descriptor) class Sid(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr + sid_rev_num = _swig_property(_security.Sid_sid_rev_num_get) + num_auths = _swig_property(_security.Sid_num_auths_get) + id_auth = _swig_property(_security.Sid_id_auth_get) + sub_auths = _swig_property(_security.Sid_sub_auths_get) def __init__(self, *args, **kwargs): _security.Sid_swiginit(self,_security.new_Sid(*args, **kwargs)) + def __repr__(self): + return "Sid(%r)" % str(self) + __swig_destroy__ = _security.delete_Sid Sid.__str__ = new_instancemethod(_security.Sid___str__,None,Sid) Sid.__eq__ = new_instancemethod(_security.Sid___eq__,None,Sid) diff --git a/source4/libcli/security/security_wrap.c b/source4/libcli/security/security_wrap.c index a10626c043..f7e3c2fb21 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.35 + * Version 1.3.36 * * 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 @@ -52,6 +52,12 @@ # endif #endif +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) @@ -2521,7 +2527,7 @@ static swig_module_info swig_module = {swig_types, 14, 0, 0, 0, 0}; #define SWIG_name "_security" -#define SWIGVERSION 0x010335 +#define SWIGVERSION 0x010336 #define SWIG_VERSION SWIGVERSION @@ -2537,6 +2543,9 @@ typedef struct security_token security_token; typedef struct security_descriptor security_descriptor; +#include "libcli/util/pyerrors.h" + + #define SWIG_From_long PyInt_FromLong @@ -2703,6 +2712,28 @@ SWIGINTERN void delete_security_token(security_token *self){ talloc_free(self); SWIGINTERN security_descriptor *new_security_descriptor(TALLOC_CTX *mem_ctx){ return security_descriptor_initialise(mem_ctx); } SWIGINTERN void delete_security_descriptor(security_descriptor *self){ talloc_free(self); } +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long (unsigned long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLong(value) : PyInt_FromLong((long)(value)); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_unsigned_SS_char (unsigned char value) +{ + return SWIG_From_unsigned_SS_long (value); +} + + +SWIGINTERNINLINE PyObject * +SWIG_From_signed_SS_char (signed char value) +{ + return SWIG_From_long (value); +} + + SWIGINTERN swig_type_info* SWIG_pchar_descriptor(void) { @@ -2834,7 +2865,6 @@ SWIGINTERN PyObject *_wrap_SecurityToken_is_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -2844,6 +2874,7 @@ SWIGINTERN PyObject *_wrap_SecurityToken_is_sid(PyObject *SWIGUNUSEDPARM(self), char * kwnames[] = { (char *) "self",(char *) "sid", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_is_sid",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); @@ -2867,10 +2898,10 @@ fail: SWIGINTERN PyObject *_wrap_SecurityToken_is_system(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; + bool result; if (!args) SWIG_fail; swig_obj[0] = args; @@ -2890,10 +2921,10 @@ fail: SWIGINTERN PyObject *_wrap_SecurityToken_is_anonymous(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; + bool result; if (!args) SWIG_fail; swig_obj[0] = args; @@ -2914,7 +2945,6 @@ SWIGINTERN PyObject *_wrap_SecurityToken_has_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -2924,6 +2954,7 @@ SWIGINTERN PyObject *_wrap_SecurityToken_has_sid(PyObject *SWIGUNUSEDPARM(self), char * kwnames[] = { (char *) "self",(char *) "sid", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_has_sid",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); @@ -2947,10 +2978,10 @@ fail: SWIGINTERN PyObject *_wrap_SecurityToken_has_builtin_administrators(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; + bool result; if (!args) SWIG_fail; swig_obj[0] = args; @@ -2970,10 +3001,10 @@ fail: SWIGINTERN PyObject *_wrap_SecurityToken_has_nt_authenticated_users(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; + bool result; if (!args) SWIG_fail; swig_obj[0] = args; @@ -2994,7 +3025,6 @@ SWIGINTERN PyObject *_wrap_SecurityToken_has_privilege(PyObject *SWIGUNUSEDPARM( PyObject *resultobj = 0; security_token *arg1 = (security_token *) 0 ; enum sec_privilege arg2 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; int val2 ; @@ -3004,6 +3034,7 @@ SWIGINTERN PyObject *_wrap_SecurityToken_has_privilege(PyObject *SWIGUNUSEDPARM( char * kwnames[] = { (char *) "self",(char *) "privilege", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:SecurityToken_has_privilege",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_token, 0 | 0 ); @@ -3072,7 +3103,6 @@ SWIGINTERN PyObject *_wrap_delete_SecurityToken(PyObject *SWIGUNUSEDPARM(self), } arg1 = (security_token *)(argp1); delete_security_token(arg1); - resultobj = SWIG_Py_Void(); return resultobj; fail: @@ -3110,7 +3140,6 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; struct security_ace *arg2 = (struct security_ace *) 0 ; - NTSTATUS result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3120,6 +3149,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM char * kwnames[] = { (char *) "self",(char *) "ace", NULL }; + NTSTATUS result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_sacl_add",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); @@ -3134,8 +3164,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM arg2 = (struct security_ace *)(argp2); result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetNTSTATUS(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3150,7 +3179,6 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; struct security_ace *arg2 = (struct security_ace *) 0 ; - NTSTATUS result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3160,6 +3188,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM char * kwnames[] = { (char *) "self",(char *) "ace", NULL }; + NTSTATUS result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_dacl_add",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); @@ -3174,8 +3203,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM arg2 = (struct security_ace *)(argp2); result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetNTSTATUS(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3190,7 +3218,6 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - NTSTATUS result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3200,6 +3227,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM char * kwnames[] = { (char *) "self",(char *) "trustee", NULL }; + NTSTATUS result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_dacl_del",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); @@ -3214,8 +3242,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM arg2 = (struct dom_sid *)(argp2); result = security_descriptor_dacl_del(arg1,(struct dom_sid const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetNTSTATUS(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3230,7 +3257,6 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - NTSTATUS result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3240,6 +3266,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM char * kwnames[] = { (char *) "self",(char *) "trustee", NULL }; + NTSTATUS result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor_sacl_del",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); @@ -3254,8 +3281,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM arg2 = (struct dom_sid *)(argp2); result = security_descriptor_sacl_del(arg1,(struct dom_sid const *)arg2); if (NT_STATUS_IS_ERR(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetNTSTATUS(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; @@ -3270,7 +3296,6 @@ SWIGINTERN PyObject *_wrap_security_descriptor___eq__(PyObject *SWIGUNUSEDPARM(s PyObject *resultobj = 0; security_descriptor *arg1 = (security_descriptor *) 0 ; struct security_descriptor *arg2 = (struct security_descriptor *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3280,6 +3305,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor___eq__(PyObject *SWIGUNUSEDPARM(s char * kwnames[] = { (char *) "self",(char *) "other", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:security_descriptor___eq__",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_security_descriptor, 0 | 0 ); @@ -3315,7 +3341,6 @@ SWIGINTERN PyObject *_wrap_delete_security_descriptor(PyObject *SWIGUNUSEDPARM(s } arg1 = (security_descriptor *)(argp1); delete_security_descriptor(arg1); - resultobj = SWIG_Py_Void(); return resultobj; fail: @@ -3334,11 +3359,102 @@ SWIGINTERN PyObject *security_descriptor_swiginit(PyObject *SWIGUNUSEDPARM(self) return SWIG_Python_InitShadowInstance(args); } +SWIGINTERN PyObject *_wrap_Sid_sid_rev_num_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint8_t result; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_sid_rev_num_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (uint8_t) ((arg1)->sid_rev_num); + resultobj = SWIG_From_unsigned_SS_char((unsigned char)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid_num_auths_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + int8_t result; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_num_auths_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (int8_t) ((arg1)->num_auths); + resultobj = SWIG_From_signed_SS_char((signed char)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid_id_auth_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint8_t *result = 0 ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_id_auth_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (uint8_t *)(uint8_t *) ((arg1)->id_auth); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_unsigned_char, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Sid_sub_auths_get(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + dom_sid *arg1 = (dom_sid *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + uint32_t *result = 0 ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Sid_sub_auths_get" "', argument " "1"" of type '" "dom_sid *""'"); + } + arg1 = (dom_sid *)(argp1); + result = (uint32_t *) ((arg1)->sub_auths); + resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_unsigned_int, 0 | 0 ); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_new_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; char *arg2 = (char *) 0 ; - dom_sid *result = 0 ; int res2 ; char *buf2 = 0 ; int alloc2 = 0 ; @@ -3346,6 +3462,7 @@ SWIGINTERN PyObject *_wrap_new_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject *arg char * kwnames[] = { (char *) "text", NULL }; + dom_sid *result = 0 ; arg1 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:new_Sid",kwnames,&obj0)) SWIG_fail; @@ -3368,10 +3485,10 @@ SWIGINTERN PyObject *_wrap_Sid___str__(PyObject *SWIGUNUSEDPARM(self), PyObject PyObject *resultobj = 0; dom_sid *arg1 = (dom_sid *) 0 ; TALLOC_CTX *arg2 = (TALLOC_CTX *) 0 ; - char *result = 0 ; void *argp1 = 0 ; int res1 = 0 ; PyObject *swig_obj[1] ; + char *result = 0 ; arg2 = NULL; if (!args) SWIG_fail; @@ -3393,7 +3510,6 @@ SWIGINTERN PyObject *_wrap_Sid___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject * PyObject *resultobj = 0; dom_sid *arg1 = (dom_sid *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -3403,6 +3519,7 @@ SWIGINTERN PyObject *_wrap_Sid___eq__(PyObject *SWIGUNUSEDPARM(self), PyObject * char * kwnames[] = { (char *) "self",(char *) "other", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Sid___eq__",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_dom_sid, 0 | 0 ); @@ -3438,7 +3555,6 @@ SWIGINTERN PyObject *_wrap_delete_Sid(PyObject *SWIGUNUSEDPARM(self), PyObject * } arg1 = (dom_sid *)(argp1); delete_dom_sid(arg1); - resultobj = SWIG_Py_Void(); return resultobj; fail: @@ -3475,13 +3591,13 @@ fail: SWIGINTERN PyObject *_wrap_privilege_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; enum sec_privilege arg1 ; - char *result = 0 ; int val1 ; int ecode1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "privilege", NULL }; + char *result = 0 ; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:privilege_name",kwnames,&obj0)) SWIG_fail; ecode1 = SWIG_AsVal_int(obj0, &val1); @@ -3500,7 +3616,6 @@ fail: SWIGINTERN PyObject *_wrap_privilege_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; char *arg1 = (char *) 0 ; - enum sec_privilege result; int res1 ; char *buf1 = 0 ; int alloc1 = 0 ; @@ -3508,6 +3623,7 @@ SWIGINTERN PyObject *_wrap_privilege_id(PyObject *SWIGUNUSEDPARM(self), PyObject char * kwnames[] = { (char *) "name", NULL }; + enum sec_privilege result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:privilege_id",kwnames,&obj0)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); @@ -3559,6 +3675,10 @@ static PyMethodDef SwigMethods[] = { { (char *)"delete_security_descriptor", (PyCFunction)_wrap_delete_security_descriptor, METH_O, NULL}, { (char *)"security_descriptor_swigregister", security_descriptor_swigregister, METH_VARARGS, NULL}, { (char *)"security_descriptor_swiginit", security_descriptor_swiginit, METH_VARARGS, NULL}, + { (char *)"Sid_sid_rev_num_get", (PyCFunction)_wrap_Sid_sid_rev_num_get, METH_O, NULL}, + { (char *)"Sid_num_auths_get", (PyCFunction)_wrap_Sid_num_auths_get, METH_O, NULL}, + { (char *)"Sid_id_auth_get", (PyCFunction)_wrap_Sid_id_auth_get, METH_O, NULL}, + { (char *)"Sid_sub_auths_get", (PyCFunction)_wrap_Sid_sub_auths_get, METH_O, NULL}, { (char *)"new_Sid", (PyCFunction) _wrap_new_Sid, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Sid___str__", (PyCFunction)_wrap_Sid___str__, METH_O, NULL}, { (char *)"Sid___eq__", (PyCFunction) _wrap_Sid___eq__, METH_VARARGS | METH_KEYWORDS, NULL}, diff --git a/source4/libcli/security/tests/bindings.py b/source4/libcli/security/tests/bindings.py index 82ce7aeba8..b539de833d 100644 --- a/source4/libcli/security/tests/bindings.py +++ b/source4/libcli/security/tests/bindings.py @@ -65,6 +65,10 @@ class DomSidTests(unittest.TestCase): sid = security.random_sid() self.assertTrue(str(sid).startswith("S-1-5-21-")) + def test_repr(self): + sid = security.random_sid() + self.assertTrue(repr(sid).startswith("Sid('S-1-5-21-")) + class PrivilegeTests(unittest.TestCase): def test_privilege_name(self): diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 43151943d3..bbfcf010ae 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -184,8 +184,8 @@ static void continue_socket(struct composite_context *creq) } state->negprot.in.capabilities = 0; unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); - dialects[0] = 0; - dialects[1] = SMB2_DIALECT_REVISION; + dialects[0] = SMB2_DIALECT_REVISION; + dialects[1] = 0; state->negprot.in.dialects = dialects; req = smb2_negprot_send(transport, &state->negprot); @@ -206,7 +206,13 @@ static void continue_resolve(struct composite_context *creq) struct smb2_connect_state *state = talloc_get_type(c->private_data, struct smb2_connect_state); const char *addr; - const char *ports[2] = { "445", NULL }; + const char **ports; + const char *default_ports[] = { "445", NULL }; + + ports = lp_parm_string_list(state, global_loadparm, NULL, "smb2", "ports", NULL); + if (ports == NULL) { + ports = default_ports; + } c->status = resolve_name_recv(creq, state, &addr); if (!composite_is_ok(c)) return; diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 64d427f889..137e2f2f12 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -279,7 +279,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ { uint16_t ofs, size; if (smb2_oob(buf, ptr, 4)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } ofs = SVAL(ptr, 0); size = SVAL(ptr, 2); @@ -288,7 +288,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); @@ -315,12 +315,12 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, /* we have only 16 bit for the size */ if (blob.length > 0xFFFF) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } /* check if there're enough room for ofs and size */ if (smb2_oob(buf, ptr, 4)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } if (blob.data == NULL) { @@ -376,7 +376,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, /* check if there're enough room for ofs and size */ if (smb2_oob(buf, ptr, 6)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } if (blob.data == NULL) { @@ -432,7 +432,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, /* check if there're enough room for ofs and size */ if (smb2_oob(buf, ptr, 8)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } if (blob.data == NULL) { @@ -488,7 +488,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, /* check if there're enough room for ofs and size */ if (smb2_oob(buf, ptr, 8)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } if (blob.data == NULL) { @@ -533,7 +533,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ uint32_t size; if (smb2_oob(buf, ptr, 6)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } ofs = SVAL(ptr, 0); size = IVAL(ptr, 2); @@ -542,7 +542,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); @@ -557,7 +557,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ { uint32_t ofs, size; if (smb2_oob(buf, ptr, 8)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } ofs = IVAL(ptr, 0); size = IVAL(ptr, 4); @@ -566,7 +566,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); @@ -584,7 +584,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem { uint32_t ofs, size; if (smb2_oob(buf, ptr, 8)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } ofs = SVAL(ptr, 0); size = IVAL(ptr, 4); @@ -593,7 +593,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem return NT_STATUS_OK; } if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); @@ -608,7 +608,7 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ { uint32_t ofs, size; if (smb2_oob(buf, ptr, 8)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; } size = IVAL(ptr, 0); ofs = IVAL(ptr, 4); @@ -617,7 +617,31 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } if (smb2_oob(buf, buf->hdr + ofs, size)) { - return NT_STATUS_BUFFER_TOO_SMALL; + return NT_STATUS_INVALID_PARAMETER; + } + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; +} + +/* + pull a uint32_t length/ uint16_t ofs/blob triple from a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_s32o16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +{ + uint32_t ofs, size; + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_INVALID_PARAMETER; + } + size = IVAL(ptr, 0); + ofs = SVAL(ptr, 4); + if (ofs == 0) { + *blob = data_blob(NULL, 0); + return NT_STATUS_OK; + } + if (smb2_oob(buf, buf->hdr + ofs, size)) { + return NT_STATUS_INVALID_PARAMETER; } *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c index de9e1e9d29..101fb00c12 100644 --- a/source4/libcli/smb2/signing.c +++ b/source4/libcli/smb2/signing.c @@ -23,7 +23,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#include "lib/crypto/crypto.h" +#include "../lib/crypto/crypto.h" /* sign an outgoing message diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index f00107de60..9d63a4a95f 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -178,6 +178,7 @@ struct smb2_request { #define SMB2_MIN_SIZE 0x42 +#define SMB2_MIN_SIZE_NO_BODY 0x40 /* offsets into header elements for a sync SMB2 request */ #define SMB2_HDR_PROTOCOL_ID 0x00 diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c index 311cea94a0..a360d8fbdf 100644 --- a/source4/libcli/smb2/util.c +++ b/source4/libcli/smb2/util.c @@ -138,7 +138,7 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname) } ZERO_STRUCT(create_parm); - create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + create_parm.in.desired_access = SEC_FILE_READ_DATA; create_parm.in.share_access = NTCREATEX_SHARE_ACCESS_READ| NTCREATEX_SHARE_ACCESS_WRITE; @@ -197,6 +197,12 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname) smb2_util_close(tree, create_parm.out.file.handle); status = smb2_util_rmdir(tree, dname); + if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { + /* it could be read-only */ + status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL); + status = smb2_util_rmdir(tree, dname); + } + if (NT_STATUS_IS_ERR(status)) { DEBUG(2,("Failed to delete %s - %s\n", dname, nt_errstr(status))); diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index e56339f96b..a4137290bb 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -234,7 +234,7 @@ static NTSTATUS connect_negprot(struct composite_context *c, NT_STATUS_NOT_OK_RETURN(status); /* next step is a session setup */ - state->session = smbcli_session_init(state->transport, state, true); + state->session = smbcli_session_init(state->transport, state, true, io->in.session_options); NT_STATUS_HAVE_NO_MEMORY(state->session); /* setup for a tconx (or at least have the structure ready to diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index 9cd02a51f4..ff4f0e7930 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -147,6 +147,7 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.workgroup = io->in.workgroup; state->connect->in.options = io->in.options; + state->connect->in.session_options = io->in.session_options; state->creq = smb_composite_connect_send(state->connect, state, io->in.resolve_ctx, event_ctx); diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index 270d71f518..dc5327a29c 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -127,7 +127,8 @@ static void fsinfo_composite_handler(struct composite_context *creq) composite fsinfo call - connects to a tree and queries a file system information */ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, - struct smb_composite_fsinfo *io) + struct smb_composite_fsinfo *io, + struct resolve_context *resolve_ctx) { struct composite_context *c; struct fsinfo_state *state; @@ -154,13 +155,14 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.workgroup = io->in.workgroup; state->connect->in.options = tree->session->transport->options; + state->connect->in.session_options = tree->session->options; c->state = COMPOSITE_STATE_IN_PROGRESS; state->stage = FSINFO_CONNECT; c->private_data = state; state->creq = smb_composite_connect_send(state->connect, state, - lp_resolve_context(global_loadparm), c->event_ctx); + resolve_ctx, c->event_ctx); if (state->creq == NULL) goto failed; @@ -197,9 +199,10 @@ NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ */ NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, - struct smb_composite_fsinfo *io) + struct smb_composite_fsinfo *io, + struct resolve_context *resolve_ctx) { - struct composite_context *c = smb_composite_fsinfo_send(tree, io); + struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx); return smb_composite_fsinfo_recv(c, mem_ctx); } diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 11ac37e257..645f5362ac 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -35,6 +35,7 @@ struct sesssetup_state { union smb_sesssetup setup; + NTSTATUS remote_status; NTSTATUS gensec_status; struct smb_composite_sesssetup *io; struct smbcli_request *req; @@ -85,10 +86,26 @@ static void request_handler(struct smbcli_request *req) DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); NTSTATUS session_key_err, nt_status; + struct smbcli_request *check_req = NULL; - c->status = smb_raw_sesssetup_recv(req, state, &state->setup); + if (req->sign_caller_checks) { + req->do_not_free = true; + check_req = req; + } + + state->remote_status = smb_raw_sesssetup_recv(req, state, &state->setup); + c->status = state->remote_status; state->req = NULL; + /* + * we only need to check the signature if the + * NT_STATUS_OK is returned + */ + if (!NT_STATUS_IS_OK(state->remote_status)) { + talloc_free(check_req); + check_req = NULL; + } + switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: state->io->out.vuid = state->setup.old.out.vuid; @@ -102,6 +119,7 @@ static void request_handler(struct smbcli_request *req) state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { + talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; @@ -120,6 +138,7 @@ static void request_handler(struct smbcli_request *req) state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { + talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; @@ -138,6 +157,7 @@ static void request_handler(struct smbcli_request *req) state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { + talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; @@ -169,12 +189,16 @@ static void request_handler(struct smbcli_request *req) state->setup.spnego.in.secblob = data_blob(NULL, 0); } - /* we need to do another round of session setup. We keep going until both sides - are happy */ - session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(session_key_err)) { - set_user_session_key(session, &session_key); - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + if (NT_STATUS_IS_OK(state->remote_status)) { + if (state->setup.spnego.in.secblob.length) { + c->status = NT_STATUS_INTERNAL_ERROR; + break; + } + session_key_err = gensec_session_key(session->gensec, &session_key); + if (NT_STATUS_IS_OK(session_key_err)) { + set_user_session_key(session, &session_key); + smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); + } } if (state->setup.spnego.in.secblob.length) { @@ -186,6 +210,9 @@ static void request_handler(struct smbcli_request *req) session->vuid = state->io->out.vuid; state->req = smb_raw_sesssetup_send(session, &state->setup); session->vuid = vuid; + if (state->req) { + state->req->sign_caller_checks = true; + } composite_continue_smb(c, state->req, request_handler, c); return; } @@ -196,6 +223,15 @@ static void request_handler(struct smbcli_request *req) break; } + if (check_req) { + check_req->sign_caller_checks = false; + if (!smbcli_request_check_sign_mac(check_req)) { + c->status = NT_STATUS_ACCESS_DENIED; + } + talloc_free(check_req); + check_req = NULL; + } + /* enforce the local signing required flag */ if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) { if (!session->transport->negotiate.sign_info.doing_signing @@ -222,11 +258,14 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, struct smb_composite_sesssetup *io, struct smbcli_request **req) { - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); 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; + DATA_BLOB session_key = data_blob(NULL, 0); int flags = CLI_CRED_NTLM_AUTH; + + smbcli_temp_set_signing(session->transport); + if (session->options.lanman_auth) { flags |= CLI_CRED_LANMAN_AUTH; } @@ -258,12 +297,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, &state->setup.nt1.in.password2, NULL, &session_key); NT_STATUS_NOT_OK_RETURN(nt_status); - - smbcli_transport_simple_set_signing(session->transport, session_key, - state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); - - 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)); @@ -277,6 +310,15 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, if (!*req) { return NT_STATUS_NO_MEMORY; } + + if (NT_STATUS_IS_OK(nt_status)) { + smbcli_transport_simple_set_signing(session->transport, session_key, + state->setup.nt1.in.password2); + set_user_session_key(session, &session_key); + + data_blob_free(&session_key); + } + return (*req)->status; } @@ -350,9 +392,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, struct smbcli_request **req) { struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); - NTSTATUS status, session_key_err; - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB null_data_blob = data_blob(NULL, 0); + NTSTATUS status; const char *chosen_oid = NULL; state->setup.spnego.level = RAW_SESSSETUP_SPNEGO; @@ -440,15 +480,18 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, } state->gensec_status = status; - session_key_err = gensec_session_key(session->gensec, &session_key); - if (NT_STATUS_IS_OK(session_key_err)) { - smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); - } - *req = smb_raw_sesssetup_send(session, &state->setup); if (!*req) { return NT_STATUS_NO_MEMORY; } + + /* + * we need to check the signature ourself + * as the session key might be the acceptor subkey + * which comes within the response itself + */ + (*req)->sign_caller_checks = true; + return (*req)->status; } diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index 7f4b9d73e4..08ca40c833 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -57,6 +57,7 @@ struct smb_composite_fetchfile { const char *workgroup; const char *filename; struct smbcli_options options; + struct smbcli_session_options session_options; struct resolve_context *resolve_ctx; } in; struct { @@ -98,6 +99,7 @@ struct smb_composite_connect { bool fallback_to_anonymous; const char *workgroup; struct smbcli_options options; + struct smbcli_session_options session_options; } in; struct { struct smbcli_tree *tree; diff --git a/source4/libcli/swig/libcli_smb.i b/source4/libcli/swig/libcli_smb.i index 4125bcf5a9..0162b7b66a 100644 --- a/source4/libcli/swig/libcli_smb.i +++ b/source4/libcli/swig/libcli_smb.i @@ -1,6 +1,6 @@ %module libcli_smb -%import "../../lib/talloc/talloc.i" +%import "../../../lib/talloc/talloc.i" %import "../../lib/events/events.i" %{ diff --git a/source4/libcli/swig/libcli_smb.py b/source4/libcli/swig/libcli_smb.py index 6e4fe036c7..4662618fd3 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.35 +# Version 1.3.36 # # 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 a3ea079b83..99bbdc7f96 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.35 + * Version 1.3.36 * * 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 @@ -52,6 +52,12 @@ # endif #endif +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) @@ -2513,7 +2519,7 @@ static swig_module_info swig_module = {swig_types, 6, 0, 0, 0, 0}; #define SWIG_name "_libcli_smb" -#define SWIGVERSION 0x010335 +#define SWIGVERSION 0x010336 #define SWIG_VERSION SWIGVERSION @@ -2603,7 +2609,6 @@ SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(s TALLOC_CTX *arg3 = (TALLOC_CTX *) 0 ; struct resolve_context *arg4 = (struct resolve_context *) 0 ; struct event_context *arg5 = (struct event_context *) 0 ; - struct smbcli_socket *result = 0 ; int res1 ; char *buf1 = 0 ; int alloc1 = 0 ; @@ -2620,8 +2625,9 @@ SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(s char * kwnames[] = { (char *) "host",(char *) "ports",(char *) "resolve_ctx",(char *) "event_ctx", NULL }; + struct smbcli_socket *result = 0 ; - arg5 = s4_event_context_init(NULL); + arg5 = event_context_init(NULL); arg3 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); |