1/* 2 Unix SMB/CIFS implementation. 3 4 handling for netlogon dgram requests 5 6 Copyright (C) Andrew Tridgell 2005 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "libcli/dgram/libdgram.h" 24#include "lib/socket/socket.h" 25#include "libcli/resolve/resolve.h" 26#include "librpc/gen_ndr/ndr_nbt.h" 27 28/* 29 send a netlogon mailslot request 30*/ 31NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, 32 struct nbt_name *dest_name, 33 struct socket_address *dest, 34 const char *mailslot, 35 struct nbt_name *src_name, 36 struct nbt_netlogon_packet *request) 37{ 38 NTSTATUS status; 39 enum ndr_err_code ndr_err; 40 DATA_BLOB blob; 41 TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); 42 43 ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, 44 dgmsock->iconv_convenience, 45 request, 46 (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); 47 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 48 talloc_free(tmp_ctx); 49 return ndr_map_error2ntstatus(ndr_err); 50 } 51 52 53 status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, 54 mailslot, 55 dest_name, dest, 56 src_name, &blob); 57 talloc_free(tmp_ctx); 58 return status; 59} 60 61 62/* 63 send a netlogon mailslot reply 64*/ 65NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, 66 struct nbt_dgram_packet *request, 67 const char *my_netbios_name, 68 const char *mailslot_name, 69 struct nbt_netlogon_response *reply) 70{ 71 NTSTATUS status; 72 DATA_BLOB blob; 73 TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); 74 struct nbt_name myname; 75 struct socket_address *dest; 76 77 status = push_nbt_netlogon_response(&blob, tmp_ctx, dgmsock->iconv_convenience, 78 reply); 79 if (!NT_STATUS_IS_OK(status)) { 80 return status; 81 } 82 83 make_nbt_name_client(&myname, my_netbios_name); 84 85 dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, 86 request->src_addr, request->src_port); 87 if (!dest) { 88 talloc_free(tmp_ctx); 89 return NT_STATUS_NO_MEMORY; 90 } 91 92 status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, 93 mailslot_name, 94 &request->data.msg.source_name, 95 dest, 96 &myname, &blob); 97 talloc_free(tmp_ctx); 98 return status; 99} 100 101 102/* 103 parse a netlogon response. The packet must be a valid mailslot packet 104*/ 105NTSTATUS dgram_mailslot_netlogon_parse_request(struct dgram_mailslot_handler *dgmslot, 106 TALLOC_CTX *mem_ctx, 107 struct nbt_dgram_packet *dgram, 108 struct nbt_netlogon_packet *netlogon) 109{ 110 DATA_BLOB data = dgram_mailslot_data(dgram); 111 enum ndr_err_code ndr_err; 112 113 ndr_err = ndr_pull_struct_blob(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon, 114 (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); 115 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 116 NTSTATUS status = ndr_map_error2ntstatus(ndr_err); 117 DEBUG(0,("Failed to parse netlogon packet of length %d: %s\n", 118 (int)data.length, nt_errstr(status))); 119 if (DEBUGLVL(10)) { 120 file_save("netlogon.dat", data.data, data.length); 121 } 122 return status; 123 } 124 return NT_STATUS_OK; 125} 126 127/* 128 parse a netlogon response. The packet must be a valid mailslot packet 129*/ 130NTSTATUS dgram_mailslot_netlogon_parse_response(struct dgram_mailslot_handler *dgmslot, 131 TALLOC_CTX *mem_ctx, 132 struct nbt_dgram_packet *dgram, 133 struct nbt_netlogon_response *netlogon) 134{ 135 NTSTATUS status; 136 DATA_BLOB data = dgram_mailslot_data(dgram); 137 138 status = pull_nbt_netlogon_response(&data, mem_ctx, dgmslot->dgmsock->iconv_convenience, netlogon); 139 if (!NT_STATUS_IS_OK(status)) { 140 return status; 141 } 142 143 return NT_STATUS_OK; 144} 145 146