diff options
author | Andrew Tridgell <tridge@samba.org> | 2008-05-20 11:37:23 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2008-05-20 11:37:23 +1000 |
commit | 9551d4027dd9bbdfa1fcb4a5a117792811ec7f29 (patch) | |
tree | cfb05907f4e142ec997d745e4e251b4a0a5ec953 /source4/libcli | |
parent | e7d993b8b26e121ff37640825b4d2f2c4d6332bf (diff) | |
parent | e533e7a7ebc8b3029cf604e63cdc6d1cf8570ccd (diff) | |
download | samba-9551d4027dd9bbdfa1fcb4a5a117792811ec7f29.tar.gz samba-9551d4027dd9bbdfa1fcb4a5a117792811ec7f29.tar.bz2 samba-9551d4027dd9bbdfa1fcb4a5a117792811ec7f29.zip |
Merge commit 'origin/v4-0-test' into vfs_smb2
(This used to be commit ffbd222d651dcddb19cacdc50cdbfeaefa816940)
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/cldap/cldap.c | 35 | ||||
-rw-r--r-- | source4/libcli/cldap/cldap.h | 7 | ||||
-rw-r--r-- | source4/libcli/config.mk | 14 | ||||
-rw-r--r-- | source4/libcli/dgram/dgramsocket.c | 2 | ||||
-rw-r--r-- | source4/libcli/dgram/libdgram.h | 35 | ||||
-rw-r--r-- | source4/libcli/dgram/netlogon.c | 45 | ||||
-rw-r--r-- | source4/libcli/dgram/ntlogon.c | 128 | ||||
-rw-r--r-- | source4/libcli/netlogon.c | 311 | ||||
-rw-r--r-- | source4/libcli/netlogon.h | 53 |
9 files changed, 437 insertions, 193 deletions
diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 614bd51d2a..860bd358d5 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -595,7 +595,6 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, struct cldap_netlogon *io) { NTSTATUS status; - enum ndr_err_code ndr_err; struct cldap_search search; struct cldap_socket *cldap; DATA_BLOB *data; @@ -618,18 +617,15 @@ NTSTATUS cldap_netlogon_recv(struct cldap_request *req, } data = search.out.response->attributes[0].values; - ndr_err = ndr_pull_union_blob_all(data, mem_ctx, - cldap->iconv_convenience, - &io->out.netlogon, - io->in.version & 0xF, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(2,("cldap failed to parse netlogon response of type 0x%02x\n", - SVAL(data->data, 0))); - dump_data(10, data->data, data->length); - return ndr_map_error2ntstatus(ndr_err); + status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience, + &io->out.netlogon); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (io->in.map_response) { + map_netlogon_samlogon_response(&io->out.netlogon); } - return NT_STATUS_OK; } @@ -704,25 +700,20 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, uint32_t version, - union nbt_cldap_netlogon *netlogon) + struct netlogon_samlogon_response *netlogon) { NTSTATUS status; - enum ndr_err_code ndr_err; struct cldap_reply reply; struct ldap_SearchResEntry response; struct ldap_Result result; TALLOC_CTX *tmp_ctx = talloc_new(cldap); DATA_BLOB blob; - ndr_err = ndr_push_union_blob(&blob, tmp_ctx, - cldap->iconv_convenience, - netlogon, version & 0xF, - (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); + status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience, + netlogon); + if (!NT_STATUS_IS_OK(status)) { + return status; } - reply.messageid = message_id; reply.dest = src; reply.response = &response; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index eb0191d0f4..7c2daf0ca2 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -20,7 +20,7 @@ */ #include "lib/util/asn1.h" -#include "librpc/gen_ndr/nbt.h" +#include "libcli/netlogon.h" struct ldap_message; @@ -161,9 +161,10 @@ struct cldap_netlogon { const char *domain_sid; int acct_control; uint32_t version; + bool map_response; } in; struct { - union nbt_cldap_netlogon netlogon; + struct netlogon_samlogon_response netlogon; } out; }; @@ -178,4 +179,4 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, struct socket_address *src, uint32_t version, - union nbt_cldap_netlogon *netlogon); + struct netlogon_samlogon_response *netlogon); diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 68d718abaf..f502091b07 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -57,6 +57,15 @@ LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \ $(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c))) +[SUBSYSTEM::LIBCLI_NETLOGON] +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT \ + NDR_SECURITY LIBSAMBA-UTIL + +LIBCLI_NETLOGON_OBJ_FILES = $(addprefix libcli/, \ + netlogon.o) + +$(eval $(call proto_header_template,$(libclisrcdir)/netlogon_proto.h,$(LIBCLI_NETLOGON_OBJ_FILES:.o=.c))) + [PYTHON::python_libcli_nbt] SWIG_FILE = swig/libcli_nbt.i PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG @@ -70,18 +79,17 @@ PUBLIC_DEPENDENCIES = LIBCLI_SMB DYNCONFIG LIBSAMBA-HOSTCONFIG python_libcli_smb_OBJ_FILES = $(libclisrcdir)/swig/libcli_smb_wrap.o [SUBSYSTEM::LIBCLI_DGRAM] -PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE +PUBLIC_DEPENDENCIES = LIBCLI_NBT LIBNDR LIBCLI_RESOLVE LIBCLI_NETLOGON LIBCLI_DGRAM_OBJ_FILES = $(addprefix $(libclisrcdir)/dgram/, \ dgramsocket.o \ mailslot.o \ netlogon.o \ - ntlogon.o \ browse.o) [SUBSYSTEM::LIBCLI_CLDAP] PUBLIC_DEPENDENCIES = LIBCLI_LDAP -PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o # PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 06b7bd5771..2cdda654ef 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -88,7 +88,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, src); + dgmslot->handler(dgmslot, packet, mailslot_name, src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 707cca8cc5..51408d029e 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "librpc/gen_ndr/nbt.h" +#include "libcli/netlogon.h" /* a datagram name request @@ -70,6 +70,7 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, + const char *mailslot_name, struct socket_address *src); struct dgram_mailslot_handler { @@ -121,33 +122,23 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, struct socket_address *dest, + const char *mailslot_name, struct nbt_name *src_name, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *my_netbios_name, const char *mailslot_name, - struct nbt_netlogon_packet *reply); -NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_netlogon_packet *netlogon); - -NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - struct socket_address *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request); -NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, - const char *my_netbios_name, - const char *mailslot_name, - struct nbt_ntlogon_packet *reply); -NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_ntlogon_packet *ntlogon); + struct nbt_netlogon_response *reply); +NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon); + +NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_response *netlogon); NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 5c7dedc7bb..b37d4a2ee6 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -32,6 +32,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, struct socket_address *dest, + const char *mailslot, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -51,7 +52,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - NBT_MAILSLOT_NETLOGON, + mailslot, dest_name, dest, src_name, &blob); talloc_free(tmp_ctx); @@ -66,22 +67,18 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *my_netbios_name, const char *mailslot_name, - struct nbt_netlogon_packet *reply) + struct nbt_netlogon_response *reply) { NTSTATUS status; - enum ndr_err_code ndr_err; DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; struct socket_address *dest; - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, - dgmsock->iconv_convenience, - reply, - (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); + status = push_nbt_netlogon_response(&blob, tmp_ctx, dgmsock->iconv_convenience, + reply); + if (!NT_STATUS_IS_OK(status)) { + return status; } make_nbt_name_client(&myname, my_netbios_name); @@ -106,10 +103,10 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, /* parse a netlogon response. The packet must be a valid mailslot packet */ -NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_netlogon_packet *netlogon) +NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_packet *netlogon) { DATA_BLOB data = dgram_mailslot_data(dgram); enum ndr_err_code ndr_err; @@ -127,3 +124,23 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, } return NT_STATUS_OK; } + +/* + parse a netlogon response. The packet must be a valid mailslot packet +*/ +NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, + TALLOC_CTX *mem_ctx, + struct nbt_dgram_packet *dgram, + struct nbt_netlogon_response *netlogon) +{ + NTSTATUS status; + DATA_BLOB data = dgram_mailslot_data(dgram); + + status = pull_nbt_netlogon_response(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c deleted file mode 100644 index 7b26ed7c00..0000000000 --- a/source4/libcli/dgram/ntlogon.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - handling for ntlogon dgram requests - - Copyright (C) Andrew Tridgell 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "libcli/dgram/libdgram.h" -#include "lib/socket/socket.h" -#include "libcli/resolve/resolve.h" -#include "librpc/gen_ndr/ndr_nbt.h" -#include "param/param.h" - -/* - send a ntlogon mailslot request -*/ -NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - struct socket_address *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request) -{ - NTSTATUS status; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, - request, - (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - - status = dgram_mailslot_send(dgmsock, msg_type, - NBT_MAILSLOT_NTLOGON, - dest_name, dest, - src_name, &blob); - talloc_free(tmp_ctx); - return status; -} - - -/* - send a ntlogon mailslot reply -*/ -NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, - struct nbt_dgram_packet *request, - const char *my_netbios_name, - const char *mailslot_name, - struct nbt_ntlogon_packet *reply) -{ - NTSTATUS status; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); - struct nbt_name myname; - struct socket_address *dest; - - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, dgmsock->iconv_convenience, reply, - (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(tmp_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - make_nbt_name_client(&myname, my_netbios_name); - - dest = socket_address_from_strings(tmp_ctx, - dgmsock->sock->backend_name, - request->src_addr, request->src_port); - if (!dest) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - - status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, - mailslot_name, - &request->data.msg.source_name, - dest, - &myname, &blob); - talloc_free(tmp_ctx); - return status; -} - - -/* - parse a ntlogon response. The packet must be a valid mailslot packet -*/ -NTSTATUS dgram_mailslot_ntlogon_parse(struct dgram_mailslot_handler *dgmslot, - TALLOC_CTX *mem_ctx, - struct nbt_dgram_packet *dgram, - struct nbt_ntlogon_packet *ntlogon) -{ - DATA_BLOB data = dgram_mailslot_data(dgram); - enum ndr_err_code ndr_err; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, ntlogon, - (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - NTSTATUS status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("Failed to parse ntlogon packet of length %d: %s\n", - (int)data.length, nt_errstr(status))); - if (DEBUGLVL(10)) { - file_save("ntlogon.dat", data.data, data.length); - } - return status; - } - return NT_STATUS_OK; -} diff --git a/source4/libcli/netlogon.c b/source4/libcli/netlogon.c new file mode 100644 index 0000000000..3ef7cf6335 --- /dev/null +++ b/source4/libcli/netlogon.c @@ -0,0 +1,311 @@ +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +#include "includes.h" +#include "libcli/netlogon.h" + +_PUBLIC_ 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; +} + +static 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; +} + +NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct netlogon_samlogon_response *response) +{ + enum ndr_err_code ndr_err; + if (response->ntver == NETLOGON_NT_VERSION_1) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt4, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40); + } else if (response->ntver & NETLOGON_NT_VERSION_5EX) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt5_ex, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags); + } else if (response->ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_push_struct_blob(data, mem_ctx, + iconv_convenience, + &response->nt5, + (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE); + } else { + DEBUG(0, ("Asked to push unknown netlogon response type 0x%02x\n", response->ntver)); + return NT_STATUS_INVALID_PARAMETER; + } + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(2,("failed to push netlogon response of type 0x%02x\n", + response->ntver)); + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} + +NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct netlogon_samlogon_response *response) +{ + uint32_t ntver; + enum ndr_err_code ndr_err; + + if (data->length < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* lmnttoken */ + if (SVAL(data->data, data->length - 4) != 0xffff) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + /* lm20token */ + if (SVAL(data->data, data->length - 2) != 0xffff) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + ntver = IVAL(data->data, data->length - 8); + + if (ntver == NETLOGON_NT_VERSION_1) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + iconv_convenience, + &response->nt4, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40); + response->ntver = NETLOGON_NT_VERSION_1; + } else if (ntver & NETLOGON_NT_VERSION_5EX) { + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(data, mem_ctx, iconv_convenience); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(ndr, NDR_SCALARS|NDR_BUFFERS, &response->nt5_ex, ntver); + if (ndr->offset < ndr->data_size) { + ndr_err = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES, + "not all bytes consumed ofs[%u] size[%u]", + ndr->offset, ndr->data_size); + } + response->ntver = NETLOGON_NT_VERSION_5EX; + + } else if (ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + iconv_convenience, + &response->nt5, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE); + response->ntver = NETLOGON_NT_VERSION_5; + } else { + DEBUG(2,("failed to parse netlogon response of type 0x%02x - unknown response type\n", + ntver)); + dump_data(10, data->data, data->length); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(2,("failed to parse netlogon response of type 0x%02x\n", + ntver)); + dump_data(10, data->data, data->length); + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} + +void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response) +{ + struct NETLOGON_SAM_LOGON_RESPONSE_EX response_5_ex; + switch (response->ntver) { + case NETLOGON_NT_VERSION_5EX: + break; + case NETLOGON_NT_VERSION_5: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->nt5.command; + response_5_ex.pdc_name = response->nt5.pdc_name; + response_5_ex.user_name = response->nt5.user_name; + response_5_ex.domain = response->nt5.domain_name; + response_5_ex.domain_uuid = response->nt5.domain_uuid; + response_5_ex.forest = response->nt5.forest; + response_5_ex.dns_domain = response->nt5.dns_domain; + response_5_ex.pdc_dns_name = response->nt5.pdc_dns_name; + response_5_ex.sockaddr.pdc_ip = response->nt5.pdc_ip; + response_5_ex.server_type = response->nt5.server_type; + response_5_ex.nt_version = response->nt5.nt_version; + response_5_ex.lmnt_token = response->nt5.lmnt_token; + response_5_ex.lm20_token = response->nt5.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->nt5_ex = response_5_ex; + break; + + case NETLOGON_NT_VERSION_1: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->nt4.command; + response_5_ex.pdc_name = response->nt4.server; + response_5_ex.user_name = response->nt4.user_name; + response_5_ex.domain = response->nt4.domain; + response_5_ex.nt_version = response->nt4.nt_version; + response_5_ex.lmnt_token = response->nt4.lmnt_token; + response_5_ex.lm20_token = response->nt4.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->nt5_ex = response_5_ex; + break; + } + return; +} + +NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct nbt_netlogon_response *response) +{ + NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE; + enum ndr_err_code ndr_err; + switch (response->response_type) { + case NETLOGON_GET_PDC: + ndr_err = ndr_push_struct_blob(data, mem_ctx, iconv_convenience, &response->get_pdc, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response_from_pdc); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data->length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data->data, data->length); + } + return status; + } + status = NT_STATUS_OK; + break; + case NETLOGON_SAMLOGON: + status = push_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon); + break; + } + return status; +} + + +NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + struct nbt_netlogon_response *response) +{ + NTSTATUS status = NT_STATUS_INVALID_NETWORK_RESPONSE; + enum netlogon_command command; + enum ndr_err_code ndr_err; + if (data->length < 4) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + command = SVAL(data->data, 0); + + switch (command) { + case NETLOGON_RESPONSE_FROM_PDC: + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, iconv_convenience, &response->get_pdc, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response_from_pdc); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", + (int)data->length, nt_errstr(status))); + if (DEBUGLVL(10)) { + file_save("netlogon.dat", data->data, data->length); + } + return status; + } + status = NT_STATUS_OK; + response->response_type = NETLOGON_GET_PDC; + break; + case LOGON_SAM_LOGON_RESPONSE: + case LOGON_SAM_LOGON_PAUSE_RESPONSE: + case LOGON_SAM_LOGON_USER_UNKNOWN: + case LOGON_SAM_LOGON_RESPONSE_EX: + case LOGON_SAM_LOGON_PAUSE_RESPONSE_EX: + case LOGON_SAM_LOGON_USER_UNKNOWN_EX: + status = pull_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon); + response->response_type = NETLOGON_SAMLOGON; + break; + + /* These levels are queries, not responses */ + case LOGON_PRIMARY_QUERY: + case NETLOGON_ANNOUNCE_UAS: + case LOGON_SAM_LOGON_REQUEST: + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + return status; + +} diff --git a/source4/libcli/netlogon.h b/source4/libcli/netlogon.h new file mode 100644 index 0000000000..b8615b55a5 --- /dev/null +++ b/source4/libcli/netlogon.h @@ -0,0 +1,53 @@ +/* + 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" +#endif /* __CLDAP_SERVER_PROTO_H__ */ |