diff options
-rw-r--r-- | source4/libcli/dgram/libdgram.h | 6 | ||||
-rw-r--r-- | source4/libcli/dgram/mailslot.c | 7 | ||||
-rw-r--r-- | source4/libcli/dgram/netlogon.c | 33 | ||||
-rw-r--r-- | source4/nbt_server/dgram/netlogon.c | 65 | ||||
-rw-r--r-- | source4/torture/nbt/dgram.c | 3 |
5 files changed, 110 insertions, 4 deletions
diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index 0b8157f0c6..163cb1e37d 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -116,14 +116,20 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, const char *mailslot_name, struct nbt_name *dest_name, const char *dest_address, + int dest_port, 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, + int dest_port, 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 *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, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 3b7fcdcd81..1035853240 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -142,6 +142,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, const char *mailslot_name, struct nbt_name *dest_name, const char *dest_address, + int dest_port, struct nbt_name *src_name, DATA_BLOB *request) { @@ -152,6 +153,10 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, struct smb_trans_body *trans; NTSTATUS status; + if (dest_port == 0) { + dest_port = lp_dgram_port(); + } + ZERO_STRUCT(packet); packet.msg_type = msg_type; packet.flags = DGRAM_FLAG_FIRST; @@ -183,7 +188,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, trans->mailslot_name = mailslot_name; trans->data = *request; - status = nbt_dgram_send(dgmsock, &packet, dest_address, lp_dgram_port()); + status = nbt_dgram_send(dgmsock, &packet, dest_address, dest_port); talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index 869e99e2fc..138cc0d484 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -34,6 +34,7 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, const char *dest_address, + int dest_port, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -51,7 +52,37 @@ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, NBT_MAILSLOT_NETLOGON, - dest_name, dest_address, src_name, &blob); + dest_name, dest_address, dest_port, + src_name, &blob); + talloc_free(tmp_ctx); + return status; +} + + +/* + send a netlogon mailslot reply +*/ +NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, + struct nbt_dgram_packet *request, + const char *mailslot_name, + struct nbt_netlogon_packet *reply) +{ + NTSTATUS status; + DATA_BLOB blob; + TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); + + status = ndr_push_struct_blob(&blob, tmp_ctx, reply, + (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_name, + &request->data.msg.source_name, + request->source, request->src_port, + &request->data.msg.dest_name, &blob); talloc_free(tmp_ctx); return status; } diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index 471145c4ac..e013742f0a 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -27,6 +27,44 @@ #include "lib/socket/socket.h" /* + reply to a GETDC request + */ +static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, + struct nbt_dgram_packet *packet, + const char *src_address, int src_port, + struct nbt_netlogon_packet *netlogon) +{ + struct nbt_name *name = &packet->data.msg.dest_name; + struct nbt_netlogon_packet reply; + struct nbt_netlogon_response_from_pdc *pdc; + + /* only answer getdc requests on the PDC or LOGON names */ + if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { + return; + } + + /* setup a GETDC reply */ + reply.command = NETLOGON_RESPONSE_FROM_PDC; + pdc = &reply.req.response; + + pdc->pdc_name = lp_netbios_name(); + pdc->unicode_pdc_name = pdc->pdc_name; + pdc->domain_name = lp_workgroup(); + pdc->nt_version = 1; + pdc->lmnt_token = 0xFFFF; + pdc->lm20_token = 0xFFFF; + + + packet->data.msg.dest_name.type = 0; + + dgram_mailslot_netlogon_reply(dgmslot->dgmsock, + packet, + netlogon->req.pdc.mailslot_name, + &reply); +} + + +/* handle incoming netlogon mailslot requests */ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, @@ -34,16 +72,41 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, const char *src_address, int src_port) { NTSTATUS status = NT_STATUS_NO_MEMORY; + struct nbtd_interface *iface = + talloc_get_type(dgmslot->private, struct nbtd_interface); struct nbt_netlogon_packet *netlogon = talloc(dgmslot, struct nbt_netlogon_packet); + struct nbtd_iface_name *iname; + struct nbt_name *name = &packet->data.msg.dest_name; + if (netlogon == NULL) goto failed; - DEBUG(2,("netlogon request from %s:%d\n", src_address, src_port)); + /* + see if the we are listening on the destination netbios name + */ + iname = nbtd_find_iname(iface, name, 0); + if (iname == NULL) { + status = NT_STATUS_BAD_NETWORK_NAME; + goto failed; + } + + DEBUG(2,("netlogon request to %s from %s:%d\n", + nbt_name_string(netlogon, name), src_address, src_port)); status = dgram_mailslot_netlogon_parse(dgmslot, netlogon, packet, netlogon); if (!NT_STATUS_IS_OK(status)) goto failed; NDR_PRINT_DEBUG(nbt_netlogon_packet, netlogon); + switch (netlogon->command) { + case NETLOGON_QUERY_FOR_PDC: + nbtd_netlogon_getdc(dgmslot, packet, src_address, src_port, netlogon); + break; + default: + DEBUG(2,("unknown netlogon op %d from %s:%d\n", + netlogon->command, src_address, src_port)); + break; + } + talloc_free(netlogon); return; diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index c5a3b61136..b62c41b17d 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -95,7 +95,8 @@ static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx, myname.type = NBT_NAME_CLIENT; myname.scope = NULL; - status = dgram_mailslot_netlogon_send(dgmsock, &name, address, &myname, &logon); + status = dgram_mailslot_netlogon_send(dgmsock, &name, address, + 0, &myname, &logon); if (!NT_STATUS_IS_OK(status)) { printf("Failed to send netlogon request - %s\n", nt_errstr(status)); goto failed; |