svn commit: samba r8212 - in branches/SAMBA_4_0/source: libcli/nbt librpc/ndr

metze at samba.org metze at samba.org
Thu Jul 7 19:49:35 GMT 2005


Author: metze
Date: 2005-07-07 19:49:35 +0000 (Thu, 07 Jul 2005)
New Revision: 8212

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

Log:
fix pushing of nbt_string's:

- we now use an ndr_token_list, for the nbt string label pointer offsets
  this avoids to scan the whole buffer

- we need to check for already send string on a per component basis
  not only for the fullname

e.g.
w2k3 response this in the CLDAP netlogon replies

forest: w2k3.vmnet1.vm.base
dns_name: sub1.
pdc_dns_name: w2k3-104.

and this will be interpreted like

forest: w2k3.vmnet1.vm.base
dns_name: sub1.w2k3.vmnet1.vm.base
pdc_dns_name: w2k3-104.w2k3.vmnet1.vm.base

metze
Modified:
   branches/SAMBA_4_0/source/libcli/nbt/nbtname.c
   branches/SAMBA_4_0/source/librpc/ndr/libndr.h


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/nbt/nbtname.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/nbt/nbtname.c	2005-07-07 19:40:25 UTC (rev 8211)
+++ branches/SAMBA_4_0/source/libcli/nbt/nbtname.c	2005-07-07 19:49:35 UTC (rev 8212)
@@ -136,53 +136,67 @@
 */
 NTSTATUS ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s)
 {
-	int i;
-	int fulllen;
-	char *fullname;
-
 	if (!(ndr_flags & NDR_SCALARS)) {
 		return NT_STATUS_OK;
 	}
 
-	if (s == NULL || *s == 0) {
-		return ndr_push_bytes(ndr, "", 1);
-	}
+	while (s && *s) {
+		NTSTATUS status;
+		char *compname;
+		size_t complen;
+		uint32_t offset;
 
+		/* see if we have pushed the remaing string allready,
+		 * if so we use a label pointer to this string
+		 */
+		status = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, False);
+		if (NT_STATUS_IS_OK(status)) {
+			uint8_t b[2];
+			
+			if (offset > 0x3FFF) {
+				return ndr_push_error(ndr, NDR_ERR_STRING,
+						      "offset for nbt string label pointer %u[%08X] > 0x00003FFF",
+						      offset, offset);
+			}
 
-	fullname = talloc_strdup(ndr, "");
-	NT_STATUS_HAVE_NO_MEMORY(fullname);
+			b[0] = 0xC0 | (offset>>8);
+			b[1] = (offset & 0xFF);
 
-	while (*s) {
-		int len = strcspn(s, ".");
-		fullname = talloc_asprintf_append(fullname, "%c%*.*s",
-						  (unsigned char)len,
-						  (unsigned char)len,
-						  (unsigned char)len, s);
-		NT_STATUS_HAVE_NO_MEMORY(fullname);
-		s += len;
-		if (*s == '.') s++;
-	}
-
-	/* see if we can find the fullname in the existing packet - if
-	   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++) {
-		if (ndr->data[i] == fullname[0] &&
-		    memcmp(fullname, &ndr->data[i], fulllen) == 0) {
-			uint8_t b[2];
-			talloc_free(fullname);
-			b[0] = 0xC0 | (i>>8);
-			b[1] = (i&0xFF);
 			return ndr_push_bytes(ndr, b, 2);
 		}
-	}
 
-	NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen));
+		complen = strcspn(s, ".");
 
-	talloc_free(fullname);
+		/* we need to make sure the length fits into 6 bytes */
+		if (complen >= 0x3F) {
+			return ndr_push_error(ndr, NDR_ERR_STRING,
+					      "component length %u[%08X] > 0x00003F",
+					      complen, complen);
+		}
 
-	return NT_STATUS_OK;
+		compname = talloc_asprintf(ndr, "%c%*.*s",
+						(unsigned char)complen,
+						(unsigned char)complen,
+						(unsigned char)complen, s);
+		NT_STATUS_HAVE_NO_MEMORY(compname);
+
+		/* remember the current componemt + the rest of the string
+		 * so it can be reused later
+		 */
+		NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset));
+
+		/* push just this component into the blob */
+		NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1));
+		talloc_free(compname);
+
+		s += complen;
+		if (*s == '.') s++;
+	}
+
+	/* if we reach the end of the string and have pushed the last component
+	 * without using a label pointer, we need to terminate the string
+	 */
+	return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
 }
 
 

Modified: branches/SAMBA_4_0/source/librpc/ndr/libndr.h
===================================================================
--- branches/SAMBA_4_0/source/librpc/ndr/libndr.h	2005-07-07 19:40:25 UTC (rev 8211)
+++ branches/SAMBA_4_0/source/librpc/ndr/libndr.h	2005-07-07 19:49:35 UTC (rev 8212)
@@ -77,6 +77,7 @@
 
 	struct ndr_token_list *switch_list;
 	struct ndr_token_list *relative_list;
+	struct ndr_token_list *nbt_string_list;
 
 	/* this is used to ensure we generate unique reference IDs */
 	uint32_t ptr_count;



More information about the samba-cvs mailing list