1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-24 13:57:43 +03:00

r6338: ADS style GETDC response now works well enough that WinXP can join

Samba4 without Samba3 nmbd
(This used to be commit f4d07d7d3b6973b503d8c98f177471dd6cebfa92)
This commit is contained in:
Andrew Tridgell 2005-04-14 07:40:23 +00:00 committed by Gerald (Jerry) Carter
parent 8c4e06004c
commit e284a26294
4 changed files with 114 additions and 10 deletions

View File

@ -144,6 +144,11 @@ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s)
return NT_STATUS_OK;
}
if (s == NULL || *s == 0) {
return ndr_push_bytes(ndr, "", 1);
}
fullname = talloc_strdup(ndr, "");
NT_STATUS_HAVE_NO_MEMORY(fullname);
@ -162,11 +167,14 @@ NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s)
so, we can use a NBT name pointer. This allows us to fit
longer names into the packet */
fulllen = strlen(fullname)+1;
for (i=0;i + fulllen < ndr->offset;i++) {
for (i=0;i + fulllen <= ndr->offset;i++) {
if (ndr->data[i] == fullname[0] &&
memcmp(fullname, &ndr->data[i], fulllen) == 0) {
uint8_t b[2];
talloc_free(fullname);
return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i);
b[0] = 0xC0 | (i>>8);
b[1] = (i&0xFF);
return ndr_push_bytes(ndr, b, 2);
}
}

View File

@ -330,11 +330,12 @@
/*******************************************/
/* \MAILSLOT\NET\NETLOGON mailslot requests */
typedef enum {
NETLOGON_QUERY_FOR_PDC = 0x7,
NETLOGON_ANNOUNCE_UAS = 0xa,
NETLOGON_RESPONSE_FROM_PDC = 0xc,
NETLOGON_QUERY_FOR_PDC2 = 0x12,
NETLOGON_RESPONSE_FROM_PDC2 = 0x17
NETLOGON_QUERY_FOR_PDC = 0x7,
NETLOGON_ANNOUNCE_UAS = 0xa,
NETLOGON_RESPONSE_FROM_PDC = 0xc,
NETLOGON_QUERY_FOR_PDC2 = 0x12,
NETLOGON_RESPONSE_FROM_PDC2 = 0x17,
NETLOGON_RESPONSE_FROM_PDC_USER = 0x19
} nbt_netlogon_command;
/* query for pdc request */
@ -371,15 +372,27 @@
uint16 lm20_token;
} nbt_netlogon_response_from_pdc;
typedef [bitmap32bit] bitmap {
NBT_SERVER_PDC = 0x00000001,
NBT_SERVER_GC = 0x00000004,
NBT_SERVER_LDAP = 0x00000008,
NBT_SERVER_DS = 0x00000010,
NBT_SERVER_KDC = 0x00000020,
NBT_SERVER_TIMESERV = 0x00000040,
NBT_SERVER_CLOSEST = 0x00000080,
NBT_SERVER_WRITABLE = 0x00000100,
NBT_SERVER_GOOD_TIMESERV = 0x00000200
} nbt_server_type;
/* response from pdc - type2 */
typedef struct {
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
uint32 server_type;
nbt_server_type server_type;
GUID domain_uuid;
nbt_string forest;
nbt_string dns_domain;
nbt_string pdc_dns_name;
astring domain;
nbt_string domain;
nbt_string pdc_name;
nbt_string user_name;
nbt_string site_name;
@ -428,6 +441,7 @@
[case(NETLOGON_ANNOUNCE_UAS)] nbt_netlogon_announce_uas uas;
[case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response;
[case(NETLOGON_RESPONSE_FROM_PDC2)] nbt_netlogon_response_from_pdc2 response2;
[case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2;
} nbt_netlogon_request;
typedef [flag(NDR_NOALIGN),public] struct {

View File

@ -65,6 +65,85 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
}
/*
reply to a ADS style GETDC request
*/
static void nbtd_netlogon_getdc2(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_pdc2 *pdc;
struct ldb_context *samctx;
const char *attrs[] = {"realm", "dnsDomain", "objectGUID", NULL};
struct ldb_message **res;
int ret;
/* only answer getdc requests on the PDC or LOGON names */
if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
return;
}
samctx = samdb_connect(packet);
if (samctx == NULL) {
DEBUG(2,("Unable to open sam in getdc reply\n"));
return;
}
/* try and find the domain */
ret = gendb_search(samctx, samctx, NULL, &res, attrs,
"(&(name=%s)(objectClass=domainDNS))", name->name);
if (ret != 1) {
DEBUG(2,("Unable to find domain '%s' in sam\n", name->name));
return;
}
/* setup a GETDC reply */
ZERO_STRUCT(reply);
if (netlogon->req.pdc2.user_name[0]) {
reply.command = NETLOGON_RESPONSE_FROM_PDC_USER;
} else {
reply.command = NETLOGON_RESPONSE_FROM_PDC2;
}
pdc = &reply.req.response2;
/* TODO: accurately depict which services we are running */
pdc->server_type =
NBT_SERVER_PDC | NBT_SERVER_GC | NBT_SERVER_LDAP |
NBT_SERVER_DS | NBT_SERVER_KDC | NBT_SERVER_TIMESERV |
NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | NBT_SERVER_GOOD_TIMESERV;
pdc->domain_uuid = samdb_result_guid(res[0], "objectGUID");
pdc->forest = samdb_result_string(res[0], "realm", lp_realm());
pdc->dns_domain = samdb_result_string(res[0], "dnsDomain", lp_realm());
/* TODO: get our full DNS name from somewhere else */
pdc->pdc_dns_name = talloc_asprintf(packet, "%s.%s",
lp_netbios_name(), pdc->dns_domain);
pdc->domain = name->name;
pdc->pdc_name = lp_netbios_name();
pdc->user_name = netlogon->req.pdc2.user_name;
/* TODO: we need to make sure these are in our DNS zone */
pdc->site_name = "Default-First-Site-Name";
pdc->site_name2 = "Default-First-Site-Name";
pdc->unknown = 0x10; /* what is this? */
pdc->unknown2 = 2; /* and this ... */
pdc->pdc_ip = socket_get_my_addr(dgmslot->dgmsock->sock, packet);
pdc->nt_version = 13;
pdc->lmnt_token = 0xFFFF;
pdc->lm20_token = 0xFFFF;
packet->data.msg.dest_name.type = 0;
dgram_mailslot_netlogon_reply(dgmslot->dgmsock,
packet,
netlogon->req.pdc2.mailslot_name,
&reply);
}
/*
handle incoming netlogon mailslot requests
*/
@ -102,6 +181,9 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
case NETLOGON_QUERY_FOR_PDC:
nbtd_netlogon_getdc(dgmslot, packet, src_address, src_port, netlogon);
break;
case NETLOGON_QUERY_FOR_PDC2:
nbtd_netlogon_getdc2(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));

View File

@ -297,7 +297,7 @@ BOOL torture_nbt_dgram(void)
BOOL ret = True;
name.name = lp_workgroup();
name.type = NBT_NAME_PDC;
name.type = NBT_NAME_LOGON;
name.scope = NULL;
/* do an initial name resolution to find its IP */