diff options
author | Andrew Bartlett <abartlet@samba.org> | 2008-05-17 13:24:29 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2008-05-17 13:24:29 +1000 |
commit | 4f557d7954eb80e566a91b2fe22f7b7e30e0b456 (patch) | |
tree | 6e656626a2631200c66869c7bef313f77ef37084 /source4 | |
parent | 842040d18490d9f6d1fed621aa36946e2becc3e1 (diff) | |
download | samba-4f557d7954eb80e566a91b2fe22f7b7e30e0b456.tar.gz samba-4f557d7954eb80e566a91b2fe22f7b7e30e0b456.tar.bz2 samba-4f557d7954eb80e566a91b2fe22f7b7e30e0b456.zip |
Show that the NTLOGON and NETLOGON mailslots are *very* similar.
Rework the mailslot infrustructure to cope, passing down the mailslot
name so that we can implement both in the same callback function.
Andrew Bartlett
(This used to be commit 89fdd77891529aa74bb920994b8b5959aae8ac2d)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/libcli/dgram/dgramsocket.c | 2 | ||||
-rw-r--r-- | source4/libcli/dgram/libdgram.h | 1 | ||||
-rw-r--r-- | source4/nbt_server/config.mk | 2 | ||||
-rw-r--r-- | source4/nbt_server/dgram/browse.c | 1 | ||||
-rw-r--r-- | source4/nbt_server/dgram/netlogon.c | 148 | ||||
-rw-r--r-- | source4/nbt_server/dgram/request.c | 4 | ||||
-rw-r--r-- | source4/nbt_server/irpc.c | 9 | ||||
-rw-r--r-- | source4/torture/nbt/dgram.c | 25 |
8 files changed, 81 insertions, 111 deletions
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 e1209e7a54..51408d029e 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -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 { diff --git a/source4/nbt_server/config.mk b/source4/nbt_server/config.mk index 84e6b661bf..eb1aea65d7 100644 --- a/source4/nbt_server/config.mk +++ b/source4/nbt_server/config.mk @@ -44,7 +44,7 @@ PRIVATE_DEPENDENCIES = \ # End SUBSYSTEM NBTD_DGRAM ####################### -NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o ntlogon.o browse.o) +NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o browse.o) ####################### # Start SUBSYSTEM NBTD diff --git a/source4/nbt_server/dgram/browse.c b/source4/nbt_server/dgram/browse.c index 2e12fa114a..36f0160e1b 100644 --- a/source4/nbt_server/dgram/browse.c +++ b/source4/nbt_server/dgram/browse.c @@ -49,6 +49,7 @@ static const char *nbt_browse_opcode_string(enum nbt_browse_opcode r) */ void nbtd_mailslot_browse_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, + const char *mailslot_name, struct socket_address *src) { struct nbt_browse_packet *browse = talloc(dgmslot, struct nbt_browse_packet); diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index 7fae6bc1f6..ae24a7cd2b 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -4,7 +4,8 @@ NBT datagram netlogon server Copyright (C) Andrew Tridgell 2005 - + 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 @@ -26,9 +27,9 @@ #include "dsdb/samdb/samdb.h" #include "auth/auth.h" #include "util/util_ldb.h" -#include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" #include "smbd/service_task.h" +#include "cldap_server/cldap_server.h" /* reply to a GETDC request @@ -36,21 +37,22 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, struct nbtd_interface *iface, struct nbt_dgram_packet *packet, + const char *mailslot_name, const struct socket_address *src, struct nbt_netlogon_packet *netlogon) { struct nbt_name *name = &packet->data.msg.dest_name; struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false); - struct nbt_netlogon_packet reply; struct nbt_netlogon_response_from_pdc *pdc; const char *ref_attrs[] = {"nETBIOSName", NULL}; struct ldb_message **ref_res; struct ldb_context *samctx; struct ldb_dn *partitions_basedn; + struct nbt_netlogon_response netlogon_response; int ret; - /* only answer getdc requests on the PDC or LOGON names */ - if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { + /* only answer getdc requests on the PDC name */ + if (name->type != NBT_NAME_PDC) { return; } @@ -72,10 +74,11 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, } /* setup a GETDC reply */ - ZERO_STRUCT(reply); - reply.command = NETLOGON_RESPONSE_FROM_PDC; - pdc = &reply.req.response; + ZERO_STRUCT(netlogon_response); + netlogon_response.response_type = NETLOGON_GET_PDC; + pdc = &netlogon_response.get_pdc; + pdc->command = NETLOGON_RESPONSE_FROM_PDC; pdc->pdc_name = lp_netbios_name(iface->nbtsrv->task->lp_ctx); pdc->unicode_pdc_name = pdc->pdc_name; pdc->domain_name = samdb_result_string(ref_res[0], "nETBIOSName", name->name);; @@ -83,38 +86,32 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, pdc->lmnt_token = 0xFFFF; pdc->lm20_token = 0xFFFF; - - packet->data.msg.dest_name.type = 0; - dgram_mailslot_netlogon_reply(reply_iface->dgmsock, packet, lp_netbios_name(iface->nbtsrv->task->lp_ctx), netlogon->req.pdc.mailslot_name, - &reply); + &netlogon_response); } /* reply to a ADS style GETDC request */ -static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, - struct nbtd_interface *iface, - struct nbt_dgram_packet *packet, - const struct socket_address *src, - struct nbt_netlogon_packet *netlogon) +static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot, + struct nbtd_interface *iface, + struct nbt_dgram_packet *packet, + const char *mailslot_name, + const struct socket_address *src, + struct nbt_netlogon_packet *netlogon) { struct nbt_name *name = &packet->data.msg.dest_name; struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false); - struct nbt_netlogon_packet reply; - struct nbt_netlogon_response_from_pdc2 *pdc; struct ldb_context *samctx; - const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL}; - const char *dom_attrs[] = {"objectGUID", NULL}; - struct ldb_message **ref_res, **dom_res; - int ret; - const char **services = lp_server_services(iface->nbtsrv->task->lp_ctx); const char *my_ip = reply_iface->ip_address; - struct ldb_dn *partitions_basedn; + struct dom_sid *sid; + struct nbt_netlogon_response netlogon_response; + NTSTATUS status; + if (!my_ip) { DEBUG(0, ("Could not obtain own IP address for datagram socket\n")); return; @@ -131,90 +128,30 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, return; } - partitions_basedn = samdb_partitions_dn(samctx, packet); - - ret = gendb_search(samctx, packet, partitions_basedn, &ref_res, ref_attrs, - "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", - name->name); - - if (ret != 1) { - DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name)); - return; + if (netlogon->req.logon.sid_size) { + if (strcasecmp(mailslot_name, NBT_MAILSLOT_NTLOGON) == 0) { + /* SID not permitted on NTLOGON (for some reason...) */ + return; + } + sid = &netlogon->req.logon.sid; + } else { + sid = NULL; } - /* try and find the domain */ - ret = gendb_search_dn(samctx, packet, - samdb_result_dn(samctx, samctx, ref_res[0], "ncName", NULL), - &dom_res, dom_attrs); - if (ret != 1) { - DEBUG(2,("Unable to find domain from reference '%s' in sam\n", - ldb_dn_get_linearized(ref_res[0]->dn))); + status = fill_netlogon_samlogon_response(samctx, packet, name->name, sid, NULL, + netlogon->req.logon.user_name, src->addr, + netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon); + if (!NT_STATUS_IS_OK(status)) { return; } - /* setup a GETDC reply */ - ZERO_STRUCT(reply); - reply.command = NETLOGON_RESPONSE_FROM_PDC2; - -#if 0 - /* newer testing shows that the reply command type is not - changed based on whether a username is given in the - reply. This was what was causing the w2k join to be so - slow */ - if (netlogon->req.pdc2.user_name[0]) { - reply.command = NETLOGON_RESPONSE_FROM_PDC_USER; - } -#endif - - pdc = &reply.req.response2; - - /* TODO: accurately depict which services we are running */ - pdc->server_type = - NBT_SERVER_PDC | NBT_SERVER_GC | - NBT_SERVER_DS | NBT_SERVER_TIMESERV | - NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | - NBT_SERVER_GOOD_TIMESERV; - - /* hmm, probably a better way to do this */ - if (str_list_check(services, "ldap")) { - pdc->server_type |= NBT_SERVER_LDAP; - } - - if (str_list_check(services, "kdc")) { - pdc->server_type |= NBT_SERVER_KDC; - } - - pdc->domain_uuid = samdb_result_guid(dom_res[0], "objectGUID"); - pdc->forest = samdb_result_string(ref_res[0], "dnsRoot", - lp_realm(iface->nbtsrv->task->lp_ctx)); - pdc->dns_domain = samdb_result_string(ref_res[0], "dnsRoot", - lp_realm(iface->nbtsrv->task->lp_ctx)); - - /* TODO: get our full DNS name from somewhere else */ - pdc->pdc_dns_name = talloc_asprintf(packet, "%s.%s", - strlower_talloc(packet, - lp_netbios_name(iface->nbtsrv->task->lp_ctx)), - pdc->dns_domain); - pdc->domain = samdb_result_string(ref_res[0], "nETBIOSName", name->name);; - pdc->pdc_name = lp_netbios_name(iface->nbtsrv->task->lp_ctx); - pdc->user_name = netlogon->req.pdc2.user_name; - /* TODO: we need to make sure these are in our DNS zone */ - pdc->server_site = "Default-First-Site-Name"; - pdc->client_site = "Default-First-Site-Name"; - pdc->unknown = 0x10; /* what is this? */ - pdc->unknown2 = 2; /* and this ... */ - pdc->pdc_ip = my_ip; - pdc->nt_version = 13; - pdc->lmnt_token = 0xFFFF; - pdc->lm20_token = 0xFFFF; - packet->data.msg.dest_name.type = 0; dgram_mailslot_netlogon_reply(reply_iface->dgmsock, packet, lp_netbios_name(iface->nbtsrv->task->lp_ctx), - netlogon->req.pdc2.mailslot_name, - &reply); + netlogon->req.logon.mailslot_name, + &netlogon_response); } @@ -223,6 +160,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, */ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, + const char *mailslot_name, struct socket_address *src) { NTSTATUS status = NT_STATUS_NO_MEMORY; @@ -246,15 +184,17 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, DEBUG(2,("netlogon request to %s from %s:%d\n", nbt_name_string(netlogon, name), src->addr, src->port)); - status = dgram_mailslot_netlogon_parse(dgmslot, netlogon, packet, netlogon); + status = dgram_mailslot_netlogon_parse_request(dgmslot, netlogon, packet, netlogon); if (!NT_STATUS_IS_OK(status)) goto failed; switch (netlogon->command) { - case NETLOGON_QUERY_FOR_PDC: - nbtd_netlogon_getdc(dgmslot, iface, packet, src, netlogon); + case LOGON_PRIMARY_QUERY: + nbtd_netlogon_getdc(dgmslot, iface, packet, mailslot_name, + src, netlogon); break; - case NETLOGON_QUERY_FOR_PDC2: - nbtd_netlogon_getdc2(dgmslot, iface, packet, src, netlogon); + case LOGON_SAM_LOGON_REQUEST: + nbtd_netlogon_samlogon(dgmslot, iface, packet, mailslot_name, + src, netlogon); break; default: DEBUG(2,("unknown netlogon op %d from %s:%d\n", diff --git a/source4/nbt_server/dgram/request.c b/source4/nbt_server/dgram/request.c index 205a544209..277b64741d 100644 --- a/source4/nbt_server/dgram/request.c +++ b/source4/nbt_server/dgram/request.c @@ -35,8 +35,10 @@ static const struct { const char *mailslot_name; dgram_mailslot_handler_t handler; } mailslot_handlers[] = { + /* Handle both NTLOGON and NETLOGON in the same function, as + * they are very similar */ { NBT_MAILSLOT_NETLOGON, nbtd_mailslot_netlogon_handler }, - { NBT_MAILSLOT_NTLOGON, nbtd_mailslot_ntlogon_handler }, + { NBT_MAILSLOT_NTLOGON, nbtd_mailslot_netlogon_handler }, { NBT_MAILSLOT_BROWSE, nbtd_mailslot_browse_handler } }; diff --git a/source4/nbt_server/irpc.c b/source4/nbt_server/irpc.c index d184d05388..3a70c98041 100644 --- a/source4/nbt_server/irpc.c +++ b/source4/nbt_server/irpc.c @@ -60,8 +60,9 @@ struct getdc_state { }; static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, - struct nbt_dgram_packet *packet, - struct socket_address *src) + struct nbt_dgram_packet *packet, + const char *mailslot_name, + struct socket_address *src) { struct getdc_state *s = talloc_get_type(dgmslot->private, struct getdc_state); @@ -69,8 +70,8 @@ static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_response netlogon; NTSTATUS status; - status = dgram_mailslot_netlogon_parse(dgmslot, packet, packet, - &netlogon); + status = dgram_mailslot_netlogon_parse_response(dgmslot, packet, packet, + &netlogon); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n", nt_errstr(status))); diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index 38cc20b3b9..ce5758977d 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -39,6 +39,7 @@ */ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, + const char *mailslot_name, struct socket_address *src) { NTSTATUS status; @@ -378,6 +379,30 @@ static bool nbt_test_ntlogon(struct torture_context *tctx) event_loop_once(dgmsock->event_ctx); } + ZERO_STRUCT(logon); + logon.command = LOGON_PRIMARY_QUERY; + 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; + + make_nbt_name_client(&myname, TEST_NAME); + + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, lp_dgram_port(tctx->lp_ctx)); + torture_assert(tctx, dest != NULL, "Error getting address"); + status = dgram_mailslot_netlogon_send(dgmsock, + &name, dest, + NBT_MAILSLOT_NTLOGON, + &myname, &logon); + torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); + + while (timeval_elapsed(&tv) < 5 && replies == 0) { + event_loop_once(dgmsock->event_ctx); + } + torture_leave_domain(join_ctx); return true; } |