From 3294ccbb6d2ce26da5b6b9b512dfc1184a153d26 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Jan 2011 12:01:42 +0100 Subject: netlogon: move netlogon helpers to ../libcli/netlogon. Guenther --- libcli/cldap/cldap.h | 2 +- libcli/nbt/wscript_build | 12 -- libcli/ndr_netlogon.c | 210 --------------------------- libcli/ndr_netlogon_proto.h | 24 ---- libcli/netlogon.c | 272 ----------------------------------- libcli/netlogon.h | 55 ------- libcli/netlogon/ndr_netlogon.c | 210 +++++++++++++++++++++++++++ libcli/netlogon/ndr_netlogon_proto.h | 24 ++++ libcli/netlogon/netlogon.c | 272 +++++++++++++++++++++++++++++++++++ libcli/netlogon/netlogon.h | 55 +++++++ libcli/netlogon/netlogon_proto.h | 28 ++++ libcli/netlogon/wscript_build | 11 ++ libcli/netlogon_proto.h | 28 ---- 13 files changed, 601 insertions(+), 602 deletions(-) delete mode 100644 libcli/ndr_netlogon.c delete mode 100644 libcli/ndr_netlogon_proto.h delete mode 100644 libcli/netlogon.c delete mode 100644 libcli/netlogon.h create mode 100644 libcli/netlogon/ndr_netlogon.c create mode 100644 libcli/netlogon/ndr_netlogon_proto.h create mode 100644 libcli/netlogon/netlogon.c create mode 100644 libcli/netlogon/netlogon.h create mode 100644 libcli/netlogon/netlogon_proto.h create mode 100644 libcli/netlogon/wscript_build delete mode 100644 libcli/netlogon_proto.h (limited to 'libcli') diff --git a/libcli/cldap/cldap.h b/libcli/cldap/cldap.h index d05e5b9936..d1197481fb 100644 --- a/libcli/cldap/cldap.h +++ b/libcli/cldap/cldap.h @@ -19,7 +19,7 @@ along with this program. If not, see . */ -#include "../libcli/netlogon.h" +#include "../libcli/netlogon/netlogon.h" struct ldap_message; struct tsocket_address; diff --git a/libcli/nbt/wscript_build b/libcli/nbt/wscript_build index 9cae6e0195..7229d12e2e 100644 --- a/libcli/nbt/wscript_build +++ b/libcli/nbt/wscript_build @@ -21,18 +21,6 @@ bld.SAMBA_BINARY('nmblookup', ) -bld.SAMBA_SUBSYSTEM('LIBCLI_NDR_NETLOGON', - source='../ndr_netlogon.c', - public_deps='ndr NDR_SECURITY' - ) - - -bld.SAMBA_SUBSYSTEM('LIBCLI_NETLOGON', - source='../netlogon.c', - public_deps='samba-util LIBCLI_NDR_NETLOGON' - ) - - bld.SAMBA_PYTHON('python_netbios', source='pynbt.c', public_deps='cli-nbt DYNCONFIG samba-hostconfig', diff --git a/libcli/ndr_netlogon.c b/libcli/ndr_netlogon.c deleted file mode 100644 index d15154d2c9..0000000000 --- a/libcli/ndr_netlogon.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - CLDAP server structures - - Copyright (C) Andrew Bartlett 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 . -*/ - -/* 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_name)); - 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_name)); - 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/libcli/ndr_netlogon_proto.h b/libcli/ndr_netlogon_proto.h deleted file mode 100644 index ca61c16138..0000000000 --- a/libcli/ndr_netlogon_proto.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _____LIBCLI_NDR_NETLOGON_PROTO_H__ -#define _____LIBCLI_NDR_NETLOGON_PROTO_H__ - -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) -/* This file was automatically generated by mkproto.pl. DO NOT EDIT */ - -/* this file contains prototypes for functions that are private - * to this subsystem or library. These functions should not be - * used outside this particular subsystem! */ - - -/* The following definitions come from ../libcli/ndr_netlogon.c */ - -enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_REQUEST *r); -enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_REQUEST *r); -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); -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); -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) - -#endif /* _____LIBCLI_NDR_NETLOGON_PROTO_H__ */ - diff --git a/libcli/netlogon.c b/libcli/netlogon.c deleted file mode 100644 index ceb1c85c56..0000000000 --- a/libcli/netlogon.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - CLDAP server structures - - Copyright (C) Andrew Bartlett 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 . -*/ - -#include "includes.h" -#include "../libcli/netlogon.h" - -NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - 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, - &response->data.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, - &response->data.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, - &response->data.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 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, - &response->data.nt4, - (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40); - response->ntver = NETLOGON_NT_VERSION_1; - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40, - &response->data.nt4); - } - - } else if (ntver & NETLOGON_NT_VERSION_5EX) { - struct ndr_pull *ndr; - ndr = ndr_pull_init_blob(data, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags( - ndr, NDR_SCALARS|NDR_BUFFERS, &response->data.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; - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_EX, - &response->data.nt5_ex); - } - - } else if (ntver & NETLOGON_NT_VERSION_5) { - ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, - &response->data.nt5, - (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE); - response->ntver = NETLOGON_NT_VERSION_5; - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE, - &response->data.nt5); - } - } 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->data.nt5.command; - response_5_ex.pdc_name = response->data.nt5.pdc_name; - response_5_ex.user_name = response->data.nt5.user_name; - response_5_ex.domain_name = response->data.nt5.domain_name; - response_5_ex.domain_uuid = response->data.nt5.domain_uuid; - response_5_ex.forest = response->data.nt5.forest; - response_5_ex.dns_domain = response->data.nt5.dns_domain; - response_5_ex.pdc_dns_name = response->data.nt5.pdc_dns_name; - response_5_ex.sockaddr.pdc_ip = response->data.nt5.pdc_ip; - response_5_ex.server_type = response->data.nt5.server_type; - response_5_ex.nt_version = response->data.nt5.nt_version; - response_5_ex.lmnt_token = response->data.nt5.lmnt_token; - response_5_ex.lm20_token = response->data.nt5.lm20_token; - response->ntver = NETLOGON_NT_VERSION_5EX; - response->data.nt5_ex = response_5_ex; - break; - - case NETLOGON_NT_VERSION_1: - ZERO_STRUCT(response_5_ex); - response_5_ex.command = response->data.nt4.command; - response_5_ex.pdc_name = response->data.nt4.pdc_name; - response_5_ex.user_name = response->data.nt4.user_name; - response_5_ex.domain_name = response->data.nt4.domain_name; - response_5_ex.nt_version = response->data.nt4.nt_version; - response_5_ex.lmnt_token = response->data.nt4.lmnt_token; - response_5_ex.lm20_token = response->data.nt4.lm20_token; - response->ntver = NETLOGON_NT_VERSION_5EX; - response->data.nt5_ex = response_5_ex; - break; - } - return; -} - -NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - 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, - &response->data.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, - &response->data.samlogon); - break; - case NETLOGON_RESPONSE2: - ndr_err = ndr_push_struct_blob(data, mem_ctx, - &response->data.response2, - (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response2); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - status = NT_STATUS_OK; - break; - } - - return status; -} - - -NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - 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, - &response->data.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_RESPONSE2: - ndr_err = ndr_pull_struct_blob(data, mem_ctx, &response->data.response2, - (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response2); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - status = NT_STATUS_OK; - response->response_type = NETLOGON_RESPONSE2; - 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, - &response->data.samlogon); - response->response_type = NETLOGON_SAMLOGON; - break; - - /* These levels are queries, not responses */ - case LOGON_PRIMARY_QUERY: - case LOGON_REQUEST: - case NETLOGON_ANNOUNCE_UAS: - case LOGON_SAM_LOGON_REQUEST: - status = NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - return status; - -} diff --git a/libcli/netlogon.h b/libcli/netlogon.h deleted file mode 100644 index 3e626ed40d..0000000000 --- a/libcli/netlogon.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - CLDAP server structures - - Copyright (C) Andrew Bartlett 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 . -*/ - -#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; - } data; - -}; - -struct nbt_netlogon_response -{ - enum {NETLOGON_GET_PDC, NETLOGON_SAMLOGON, NETLOGON_RESPONSE2} response_type; - union { - struct nbt_netlogon_response_from_pdc get_pdc; - struct netlogon_samlogon_response samlogon; - struct nbt_netlogon_response2 response2; - } data; -}; - -#include "../libcli/netlogon_proto.h" -#include "../libcli/ndr_netlogon_proto.h" -#endif /* __CLDAP_SERVER_PROTO_H__ */ diff --git a/libcli/netlogon/ndr_netlogon.c b/libcli/netlogon/ndr_netlogon.c new file mode 100644 index 0000000000..7d6aa974b0 --- /dev/null +++ b/libcli/netlogon/ndr_netlogon.c @@ -0,0 +1,210 @@ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 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 . +*/ + +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +#include "includes.h" +#include "../libcli/netlogon/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_name)); + 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_name)); + 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/libcli/netlogon/ndr_netlogon_proto.h b/libcli/netlogon/ndr_netlogon_proto.h new file mode 100644 index 0000000000..ca61c16138 --- /dev/null +++ b/libcli/netlogon/ndr_netlogon_proto.h @@ -0,0 +1,24 @@ +#ifndef _____LIBCLI_NDR_NETLOGON_PROTO_H__ +#define _____LIBCLI_NDR_NETLOGON_PROTO_H__ + +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) +/* This file was automatically generated by mkproto.pl. DO NOT EDIT */ + +/* this file contains prototypes for functions that are private + * to this subsystem or library. These functions should not be + * used outside this particular subsystem! */ + + +/* The following definitions come from ../libcli/ndr_netlogon.c */ + +enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_REQUEST *r); +enum ndr_err_code ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull *ndr, int ndr_flags, struct NETLOGON_SAM_LOGON_REQUEST *r); +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); +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); +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) + +#endif /* _____LIBCLI_NDR_NETLOGON_PROTO_H__ */ + diff --git a/libcli/netlogon/netlogon.c b/libcli/netlogon/netlogon.c new file mode 100644 index 0000000000..d82a2013b8 --- /dev/null +++ b/libcli/netlogon/netlogon.c @@ -0,0 +1,272 @@ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 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 . +*/ + +#include "includes.h" +#include "../libcli/netlogon/netlogon.h" + +NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + 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, + &response->data.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, + &response->data.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, + &response->data.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 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, + &response->data.nt4, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40); + response->ntver = NETLOGON_NT_VERSION_1; + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40, + &response->data.nt4); + } + + } else if (ntver & NETLOGON_NT_VERSION_5EX) { + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(data, mem_ctx); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags( + ndr, NDR_SCALARS|NDR_BUFFERS, &response->data.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; + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_EX, + &response->data.nt5_ex); + } + + } else if (ntver & NETLOGON_NT_VERSION_5) { + ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, + &response->data.nt5, + (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE); + response->ntver = NETLOGON_NT_VERSION_5; + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE, + &response->data.nt5); + } + } 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->data.nt5.command; + response_5_ex.pdc_name = response->data.nt5.pdc_name; + response_5_ex.user_name = response->data.nt5.user_name; + response_5_ex.domain_name = response->data.nt5.domain_name; + response_5_ex.domain_uuid = response->data.nt5.domain_uuid; + response_5_ex.forest = response->data.nt5.forest; + response_5_ex.dns_domain = response->data.nt5.dns_domain; + response_5_ex.pdc_dns_name = response->data.nt5.pdc_dns_name; + response_5_ex.sockaddr.pdc_ip = response->data.nt5.pdc_ip; + response_5_ex.server_type = response->data.nt5.server_type; + response_5_ex.nt_version = response->data.nt5.nt_version; + response_5_ex.lmnt_token = response->data.nt5.lmnt_token; + response_5_ex.lm20_token = response->data.nt5.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->data.nt5_ex = response_5_ex; + break; + + case NETLOGON_NT_VERSION_1: + ZERO_STRUCT(response_5_ex); + response_5_ex.command = response->data.nt4.command; + response_5_ex.pdc_name = response->data.nt4.pdc_name; + response_5_ex.user_name = response->data.nt4.user_name; + response_5_ex.domain_name = response->data.nt4.domain_name; + response_5_ex.nt_version = response->data.nt4.nt_version; + response_5_ex.lmnt_token = response->data.nt4.lmnt_token; + response_5_ex.lm20_token = response->data.nt4.lm20_token; + response->ntver = NETLOGON_NT_VERSION_5EX; + response->data.nt5_ex = response_5_ex; + break; + } + return; +} + +NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + 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, + &response->data.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, + &response->data.samlogon); + break; + case NETLOGON_RESPONSE2: + ndr_err = ndr_push_struct_blob(data, mem_ctx, + &response->data.response2, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response2); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + status = NT_STATUS_OK; + break; + } + + return status; +} + + +NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + 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, + &response->data.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_RESPONSE2: + ndr_err = ndr_pull_struct_blob(data, mem_ctx, &response->data.response2, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response2); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + status = NT_STATUS_OK; + response->response_type = NETLOGON_RESPONSE2; + 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, + &response->data.samlogon); + response->response_type = NETLOGON_SAMLOGON; + break; + + /* These levels are queries, not responses */ + case LOGON_PRIMARY_QUERY: + case LOGON_REQUEST: + case NETLOGON_ANNOUNCE_UAS: + case LOGON_SAM_LOGON_REQUEST: + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + return status; + +} diff --git a/libcli/netlogon/netlogon.h b/libcli/netlogon/netlogon.h new file mode 100644 index 0000000000..9bf346af26 --- /dev/null +++ b/libcli/netlogon/netlogon.h @@ -0,0 +1,55 @@ +/* + Unix SMB/CIFS implementation. + + CLDAP server structures + + Copyright (C) Andrew Bartlett 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 . +*/ + +#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; + } data; + +}; + +struct nbt_netlogon_response +{ + enum {NETLOGON_GET_PDC, NETLOGON_SAMLOGON, NETLOGON_RESPONSE2} response_type; + union { + struct nbt_netlogon_response_from_pdc get_pdc; + struct netlogon_samlogon_response samlogon; + struct nbt_netlogon_response2 response2; + } data; +}; + +#include "../libcli/netlogon/netlogon_proto.h" +#include "../libcli/netlogon/ndr_netlogon_proto.h" +#endif /* __CLDAP_SERVER_PROTO_H__ */ diff --git a/libcli/netlogon/netlogon_proto.h b/libcli/netlogon/netlogon_proto.h new file mode 100644 index 0000000000..53c7d004ee --- /dev/null +++ b/libcli/netlogon/netlogon_proto.h @@ -0,0 +1,28 @@ +#ifndef _____LIBCLI_NETLOGON_PROTO_H__ +#define _____LIBCLI_NETLOGON_PROTO_H__ + +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) +/* This file was automatically generated by mkproto.pl. DO NOT EDIT */ + +/* this file contains prototypes for functions that are private + * to this subsystem or library. These functions should not be + * used outside this particular subsystem! */ + + +/* The following definitions come from ../libcli/netlogon.c */ + +NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct netlogon_samlogon_response *response); +NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct netlogon_samlogon_response *response); +void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response); +NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct nbt_netlogon_response *response); +NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, + struct nbt_netlogon_response *response); +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) + +#endif /* _____LIBCLI_NETLOGON_PROTO_H__ */ + diff --git a/libcli/netlogon/wscript_build b/libcli/netlogon/wscript_build new file mode 100644 index 0000000000..6c5e57ba67 --- /dev/null +++ b/libcli/netlogon/wscript_build @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +bld.SAMBA_SUBSYSTEM('LIBCLI_NDR_NETLOGON', + source='ndr_netlogon.c', + public_deps='ndr NDR_SECURITY' + ) + +bld.SAMBA_SUBSYSTEM('LIBCLI_NETLOGON', + source='netlogon.c', + public_deps='samba-util LIBCLI_NDR_NETLOGON' + ) diff --git a/libcli/netlogon_proto.h b/libcli/netlogon_proto.h deleted file mode 100644 index 53c7d004ee..0000000000 --- a/libcli/netlogon_proto.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _____LIBCLI_NETLOGON_PROTO_H__ -#define _____LIBCLI_NETLOGON_PROTO_H__ - -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) -/* This file was automatically generated by mkproto.pl. DO NOT EDIT */ - -/* this file contains prototypes for functions that are private - * to this subsystem or library. These functions should not be - * used outside this particular subsystem! */ - - -/* The following definitions come from ../libcli/netlogon.c */ - -NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - struct netlogon_samlogon_response *response); -NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - struct netlogon_samlogon_response *response); -void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response); -NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - struct nbt_netlogon_response *response); -NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx, - struct nbt_netlogon_response *response); -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) - -#endif /* _____LIBCLI_NETLOGON_PROTO_H__ */ - -- cgit