diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-04-06 11:17:08 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:11:27 -0500 |
commit | 7c6c366150022d6a745dcf18ed67bd264bc9c55d (patch) | |
tree | c43db606012e52a129179bef0b489c34a65a8036 /source4 | |
parent | 567a74690c9536f464844d647b9fe21ca56b53f3 (diff) | |
download | samba-7c6c366150022d6a745dcf18ed67bd264bc9c55d.tar.gz samba-7c6c366150022d6a745dcf18ed67bd264bc9c55d.tar.bz2 samba-7c6c366150022d6a745dcf18ed67bd264bc9c55d.zip |
r6223: added a bit more datagram infrastructure and the beginnings of a test
suite. The NBT-DGRAM test does a UDP/138 netlogon request, to which a
windows server sends a reply, but the windows server sends the reply
to the wrong port (it always sends to 138), so the test suite doesn't
see it.
(This used to be commit a7634625dbc944dd8256a822be290010f341a571)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/config.mk | 3 | ||||
-rw-r--r-- | source4/libcli/dgram/libdgram.h | 16 | ||||
-rw-r--r-- | source4/libcli/dgram/mailslot.c | 61 | ||||
-rw-r--r-- | source4/libcli/dgram/netlogon.c | 58 | ||||
-rw-r--r-- | source4/librpc/idl/nbt.idl | 38 | ||||
-rw-r--r-- | source4/torture/config.mk | 3 | ||||
-rw-r--r-- | source4/torture/nbt/dgram.c | 124 | ||||
-rw-r--r-- | source4/torture/torture.c | 1 |
8 files changed, 291 insertions, 13 deletions
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index f90f9907ad..56e923daa2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -38,7 +38,8 @@ REQUIRED_SUBSYSTEMS = LIBNDR_RAW NDR_NBT SOCKET LIBCLI_COMPOSITE_BASE LIBEVENTS [SUBSYSTEM::LIBCLI_DGRAM] ADD_OBJ_FILES = \ libcli/dgram/dgramsocket.o \ - libcli/dgram/mailslot.o + libcli/dgram/mailslot.o \ + libcli/dgram/netlogon.o NOPROTO=YES REQUIRED_SUBSYSTEMS = LIBCLI_NBT diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 866877e341..482fd86980 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -111,8 +111,18 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms void *private); - - - +NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, + enum dgram_msg_type msg_type, + const char *mailslot_name, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + DATA_BLOB *request); + +NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + struct nbt_netlogon_packet *request); diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index da9b6cdd20..89aab9c874 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -115,9 +115,9 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms /* try a 100 times at most */ for (i=0;i<100;i++) { - name = talloc_asprintf(dgmsock, "%s%u", + name = talloc_asprintf(dgmsock, "%s%03u", mailslot_name, - generate_random() % UINT16_MAX); + generate_random() % 1000); if (name == NULL) return NULL; if (dgram_mailslot_find(dgmsock, name)) { talloc_free(name); @@ -130,3 +130,60 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name)); return NULL; } + + +/* + send a mailslot request +*/ +NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, + enum dgram_msg_type msg_type, + const char *mailslot_name, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + DATA_BLOB *request) +{ + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + struct nbt_dgram_packet packet; + struct dgram_message *msg; + struct dgram_smb_packet *smb; + struct smb_trans_body *trans; + NTSTATUS status; + + ZERO_STRUCT(packet); + packet.msg_type = msg_type; + packet.flags = DGRAM_FLAG_FIRST; + packet.dgram_id = generate_random() % UINT16_MAX; + packet.source = socket_get_my_addr(dgmsock->sock, tmp_ctx); + packet.src_port = socket_get_my_port(dgmsock->sock); + + msg = &packet.data.msg; + /* this length calculation is very crude - it should be based on gensize + calls */ + msg->length = 138 + strlen(mailslot_name) + request->length; + msg->offset = 0; + + msg->source_name = *src_name; + msg->dest_name = *dest_name; + msg->dgram_body_type = DGRAM_SMB; + + smb = &msg->body.smb; + smb->smb_command = SMB_TRANSACTION; + + trans = &smb->body.trans; + trans->total_data_count = request->length; + trans->timeout = (uint32_t)-1; + trans->data_count = request->length; + trans->data_offset = 70 + strlen(mailslot_name); + trans->opcode = 1; /* write mail slot */ + trans->priority = 1; + trans->class = 2; + trans->mailslot_name = mailslot_name; + trans->data = *request; + + status = nbt_dgram_send(dgmsock, &packet, dest_address, lp_dgram_port()); + + talloc_free(tmp_ctx); + + return status; +} diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c new file mode 100644 index 0000000000..1f3a3d6c62 --- /dev/null +++ b/source4/libcli/dgram/netlogon.c @@ -0,0 +1,58 @@ +/* + Unix SMB/CIFS implementation. + + handling for netlogon 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/events/events.h" +#include "dlinklist.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" +#include "librpc/gen_ndr/ndr_nbt.h" + +/* + send a netlogon mailslot request +*/ +NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, + struct nbt_name *dest_name, + const char *dest_address, + struct nbt_name *src_name, + struct nbt_netlogon_packet *request) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + + status = ndr_push_struct_blob(&blob, tmp_ctx, request, + (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, + "\\MAILSLOT\\NET\\NETLOGON", + dest_name, dest_address, src_name, &blob); + talloc_free(tmp_ctx); + return status; +} + diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl index cd009530d1..09738820bb 100644 --- a/source4/librpc/idl/nbt.idl +++ b/source4/librpc/idl/nbt.idl @@ -200,16 +200,16 @@ interface nbt } dgram_msg_type; typedef [bitmap8bit] bitmap { - DGRAM_FLAG_MORE = 0x80, - DGRAM_FLAG_FIRST = 0x40, - DGRAM_FLAG_NODE_TYPE = 0x30 + DGRAM_FLAG_MORE = 0x01, + DGRAM_FLAG_FIRST = 0x02, + DGRAM_FLAG_NODE_TYPE = 0x0C } dgram_flags; typedef [enum8bit] enum { DGRAM_NODE_B = 0x00, - DGRAM_NODE_P = 0x10, - DGRAM_NODE_M = 0x20, - DGRAM_NODE_NBDD = 0x30 + DGRAM_NODE_P = 0x04, + DGRAM_NODE_M = 0x08, + DGRAM_NODE_NBDD = 0x0C } dgram_node_type; /* a dgram_message is the main dgram body in general use */ @@ -317,4 +317,30 @@ interface nbt uint16 src_port; [switch_is(msg_type)] dgram_data data; } nbt_dgram_packet; + + + /* \MAILSLOT\NET\NETLOGON mailslot requests */ + typedef [enum8bit] enum { + NETLOGON_QUERY_FOR_PDC = 0x7 + } nbt_netlogon_command; + + /* query for pdc request */ + typedef struct { + astring computer_name; + astring mailslot_name; + nstring unicode_name; + uint32 nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } nbt_netlogon_query_for_pdc; + + typedef [nodiscriminant] union { + [case(NETLOGON_QUERY_FOR_PDC)] nbt_netlogon_query_for_pdc pdc; + } nbt_netlogon_request; + + typedef [flag(NDR_NOALIGN),public] struct { + nbt_netlogon_command command; + uint8 pad; + [switch_is(command)] nbt_netlogon_request req; + } nbt_netlogon_packet; } diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 80fdefcf36..e8920e6e57 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -176,7 +176,8 @@ ADD_OBJ_FILES = \ torture/nbt/register.o \ torture/nbt/wins.o \ torture/nbt/winsbench.o \ - torture/nbt/winsreplication.o + torture/nbt/winsreplication.o \ + torture/nbt/dgram.o REQUIRED_SUBSYSTEMS = \ LIBSMB LIBCLI_WINS # End SUBSYSTEM TORTURE_NBT diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c new file mode 100644 index 0000000000..c87940a94d --- /dev/null +++ b/source4/torture/nbt/dgram.c @@ -0,0 +1,124 @@ +/* + Unix SMB/CIFS implementation. + + NBT dgram testing + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "libcli/nbt/libnbt.h" +#include "libcli/dgram/libdgram.h" +#include "librpc/gen_ndr/ndr_nbt.h" +#include "lib/socket/socket.h" +#include "lib/events/events.h" + +#define TEST_NAME "TORTURE_TEST" + +/* + reply handler for netlogon request +*/ +static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, + struct nbt_dgram_packet *packet, + const char *src_address, int src_port) +{ + printf("netlogon reply from %s:%d\n", src_address, src_port); +} + +/* test UDP/138 netlogon requests */ +static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx, + struct nbt_name name, const char *address) +{ + struct dgram_mailslot_handler *dgmslot; + struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL); + const char *myaddress = talloc_strdup(mem_ctx, iface_best_ip(address)); + struct nbt_netlogon_packet logon; + struct nbt_name myname; + NTSTATUS status; + int timelimit = lp_parm_int(-1, "torture", "timelimit", 10); + struct timeval tv = timeval_current(); + + socket_listen(dgmsock->sock, myaddress, 0, 0, 0); + + /* setup a temporary mailslot listener for replies */ + dgmslot = dgram_mailslot_temp(dgmsock, "\\MAILSLOT\\NET\\GETDC", + netlogon_handler, NULL); + + + ZERO_STRUCT(logon); + logon.command = NETLOGON_QUERY_FOR_PDC; + logon.req.pdc.computer_name = TEST_NAME; + logon.req.pdc.mailslot_name = dgmslot->mailslot_name; + logon.req.pdc.unicode_name = TEST_NAME; + logon.req.pdc.nt_version = 1; + logon.req.pdc.lmnt_token = 0xFFFF; + logon.req.pdc.lm20_token = 0xFFFF; + + myname.name = TEST_NAME; + myname.type = NBT_NAME_CLIENT; + myname.scope = NULL; + + status = dgram_mailslot_netlogon_send(dgmsock, &name, address, &myname, &logon); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to send netlogon request - %s\n", nt_errstr(status)); + goto failed; + } + + + while (timeval_elapsed(&tv) < timelimit) { + event_loop_once(dgmsock->event_ctx); + } + + talloc_free(dgmsock); + return True; + +failed: + talloc_free(dgmsock); + return False; +} + + +/* + test nbt dgram operations +*/ +BOOL torture_nbt_dgram(void) +{ + const char *address; + struct nbt_name name; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + NTSTATUS status; + BOOL ret = True; + + name.name = lp_parm_string(-1, "torture", "host"); + name.type = NBT_NAME_PDC; + name.scope = NULL; + + /* do an initial name resolution to find its IP */ + status = resolve_name(&name, mem_ctx, &address); + if (!NT_STATUS_IS_OK(status)) { + printf("Failed to resolve %s - %s\n", + name.name, nt_errstr(status)); + talloc_free(mem_ctx); + return False; + } + + ret &= nbt_test_netlogon(mem_ctx, name, address); + + talloc_free(mem_ctx); + + return ret; +} diff --git a/source4/torture/torture.c b/source4/torture/torture.c index eb4dd0b84a..7c8c5131eb 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -2415,6 +2415,7 @@ static struct { {"NBT-REGISTER", torture_nbt_register, 0}, {"NBT-WINS", torture_nbt_wins, 0}, {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0}, + {"NBT-DGRAM", torture_nbt_dgram, 0}, /* libnet tests */ {"NET-USERINFO", torture_userinfo, 0}, |