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:
parent
8c4e06004c
commit
e284a26294
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user