svn commit: samba r6338 - in branches/SAMBA_4_0/source: libcli/nbt librpc/idl nbt_server/dgram torture/nbt

tridge at samba.org tridge at samba.org
Thu Apr 14 07:40:24 GMT 2005


Author: tridge
Date: 2005-04-14 07:40:23 +0000 (Thu, 14 Apr 2005)
New Revision: 6338

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=6338

Log:
ADS style GETDC response now works well enough that WinXP can join
Samba4 without Samba3 nmbd

Modified:
   branches/SAMBA_4_0/source/libcli/nbt/nbtname.c
   branches/SAMBA_4_0/source/librpc/idl/nbt.idl
   branches/SAMBA_4_0/source/nbt_server/dgram/netlogon.c
   branches/SAMBA_4_0/source/torture/nbt/dgram.c


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/nbt/nbtname.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/nbt/nbtname.c	2005-04-14 06:20:54 UTC (rev 6337)
+++ branches/SAMBA_4_0/source/libcli/nbt/nbtname.c	2005-04-14 07:40:23 UTC (rev 6338)
@@ -144,6 +144,11 @@
 		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 @@
 	   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);
 		}
 	}
 

Modified: branches/SAMBA_4_0/source/librpc/idl/nbt.idl
===================================================================
--- branches/SAMBA_4_0/source/librpc/idl/nbt.idl	2005-04-14 06:20:54 UTC (rev 6337)
+++ branches/SAMBA_4_0/source/librpc/idl/nbt.idl	2005-04-14 07:40:23 UTC (rev 6338)
@@ -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 {

Modified: branches/SAMBA_4_0/source/nbt_server/dgram/netlogon.c
===================================================================
--- branches/SAMBA_4_0/source/nbt_server/dgram/netlogon.c	2005-04-14 06:20:54 UTC (rev 6337)
+++ branches/SAMBA_4_0/source/nbt_server/dgram/netlogon.c	2005-04-14 07:40:23 UTC (rev 6338)
@@ -66,6 +66,85 @@
 
 
 /*
+  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
 */
 void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, 
@@ -102,6 +181,9 @@
 	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));

Modified: branches/SAMBA_4_0/source/torture/nbt/dgram.c
===================================================================
--- branches/SAMBA_4_0/source/torture/nbt/dgram.c	2005-04-14 06:20:54 UTC (rev 6337)
+++ branches/SAMBA_4_0/source/torture/nbt/dgram.c	2005-04-14 07:40:23 UTC (rev 6338)
@@ -297,7 +297,7 @@
 	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 */



More information about the samba-cvs mailing list