The Samba-Bugzilla – Attachment 10 Details for
Bug 96
net ads cldap incorrectly parses response (no DNS decompression)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to add DNS decompression support
cldap_dns_strings.patch (text/plain), 9.70 KB, created by
Anthony Liguori
on 2003-05-19 10:41:56 UTC
(
hide
)
Description:
Patch to add DNS decompression support
Filename:
MIME Type:
Creator:
Anthony Liguori
Created:
2003-05-19 10:41:56 UTC
Size:
9.70 KB
patch
obsolete
>Index: source/utils/net_ads_cldap.c >=================================================================== >RCS file: /cvsroot/samba/source/utils/net_ads_cldap.c,v >retrieving revision 1.5.2.4 >diff -u -r1.5.2.4 net_ads_cldap.c >--- source/utils/net_ads_cldap.c 17 Mar 2003 23:04:03 -0000 1.5.2.4 >+++ source/utils/net_ads_cldap.c 19 May 2003 16:13:24 -0000 >@@ -24,28 +24,28 @@ > > #ifdef HAVE_ADS > >-struct netlogon_string { >- uint32 comp_len; >- char **component; >- uint8 extra_flag; >-}; >+#define MAX_DNS_LABEL 255 + 1 > > struct cldap_netlogon_reply { > uint32 type; > uint32 flags; > GUID guid; > >- struct netlogon_string forest; >- struct netlogon_string domain; >- struct netlogon_string hostname; >- >- struct netlogon_string netbios_domain; >- struct netlogon_string netbios_hostname; >- >- struct netlogon_string user_name; >- struct netlogon_string site_name; >- >- struct netlogon_string unk0; >+ char forest[MAX_DNS_LABEL]; >+ char unk0[MAX_DNS_LABEL]; >+ char domain[MAX_DNS_LABEL]; >+ char hostname[MAX_DNS_LABEL]; >+ >+ char netbios_domain[MAX_DNS_LABEL]; >+ char unk1[MAX_DNS_LABEL]; >+ char netbios_hostname[MAX_DNS_LABEL]; >+ >+ char unk2[MAX_DNS_LABEL]; >+ char user_name[MAX_DNS_LABEL]; >+ char unk3[MAX_DNS_LABEL]; >+ char site_name[MAX_DNS_LABEL]; >+ char unk4[MAX_DNS_LABEL]; >+ char site_name_2[MAX_DNS_LABEL]; > > uint32 version; > uint16 lmnt_token; >@@ -53,38 +53,69 @@ > }; > > /* >- These strings are rather interesting... They are composed of a series of >- length encoded strings, terminated by either 1) a zero length string or 2) >- a 0xc0 byte with what appears to be a one byte flags immediately following. >+ These seem to be strings as described in RFC1035 4.1.4 and can be: >+ >+ - a sequence of labels ending in a zero octet >+ - a pointer >+ - a sequence of labels ending with a pointer >+ >+ A label is a byte where the first two bits must be zero and the remaining >+ bits represent the length of the label followed by the label itself. >+ Therefore, the length of a label is at max 64 bytes. Under RFC1035, a >+ sequence of labels cannot exceed 255 bytes. >+ >+ A pointer consists of a 14 bit offset from the beginning of the data. >+ >+ struct ptr { >+ unsigned ident:2; // must be 11 >+ unsigned offset:14; // from the beginning of data >+ }; >+ >+ This is used as a method to compress the packet by eliminated duplicate >+ domain components. Since a UDP packet should probably be < 512 bytes and a >+ DNS name can be up to 255 bytes, this actually makes a lot of sense. > */ >-static unsigned pull_netlogon_string(struct netlogon_string *ret,const char *d) >+static unsigned pull_netlogon_string(char *ret, const char *ptr, >+ const char *data) > { >- const char *p = (const char *)d; >- >- ZERO_STRUCTP(ret); >+ char *pret = ret; >+ int followed_ptr = 0; >+ unsigned ret_len = 0; > >+ memset(pret, 0, MAX_DNS_LABEL); > do { >- unsigned len = (unsigned char)*p; >- p++; >+ if ((*ptr & 0xc0) == 0xc0) { >+ uint16 len; > >- if (len > 0 && len != 0xc0) { >- ret->component = realloc(ret->component, >- ++ret->comp_len * >- sizeof(char *)); >- >- ret->component[ret->comp_len - 1] = >- smb_xstrndup(p, len); >- p += len; >- } else { >- if (len == 0xc0) { >- ret->extra_flag = *p; >- p++; >- }; >- break; >+ if (!followed_ptr) { >+ ret_len += 2; >+ followed_ptr = 1; >+ } >+ len = ((ptr[0] & 0x3f) << 8) | ptr[1]; >+ ptr = data + len; >+ } else if (*ptr) { >+ uint8 len = (uint8)*(ptr++); >+ >+ if ((pret - ret + len + 1) >= MAX_DNS_LABEL) { >+ d_printf("DC returning too long DNS name\n"); >+ return 0; >+ } >+ >+ if (pret != ret) { >+ *pret = '.'; >+ pret++; >+ } >+ memcpy(pret, ptr, len); >+ pret += len; >+ ptr += len; >+ >+ if (!followed_ptr) { >+ ret_len += (len + 1); >+ } > } >- } while (1); >+ } while (*ptr); > >- return (p - d); >+ return ret_len ? ret_len : 1; > } > > /* >@@ -95,7 +126,11 @@ > { > ASN1_DATA data; > char ntver[4]; >+#ifdef CLDAP_USER_QUERY >+ char aac[4]; > >+ SIVAL(aac, 0, 0x00000180); >+#endif > SIVAL(ntver, 0, ntversion); > > memset(&data, 0, sizeof(data)); >@@ -121,6 +156,18 @@ > asn1_write_OctetString(&data, hostname, strlen(hostname)); > asn1_pop_tag(&data); > >+#ifdef CLDAP_USER_QUERY >+ asn1_push_tag(&data, ASN1_CONTEXT(3)); >+ asn1_write_OctetString(&data, "User", 4); >+ asn1_write_OctetString(&data, "SAMBA$", 6); >+ asn1_pop_tag(&data); >+ >+ asn1_push_tag(&data, ASN1_CONTEXT(3)); >+ asn1_write_OctetString(&data, "AAC", 4); >+ asn1_write_OctetString(&data, aac, 4); >+ asn1_pop_tag(&data); >+#endif >+ > asn1_push_tag(&data, ASN1_CONTEXT(3)); > asn1_write_OctetString(&data, "NtVer", 5); > asn1_write_OctetString(&data, ntver, 4); >@@ -144,7 +191,6 @@ > d_printf("failed to send cldap query (%s)\n", strerror(errno)); > } > >- file_save("cldap_query.dat", data.data, data.length); > asn1_free(&data); > > return 0; >@@ -173,8 +219,6 @@ > } > blob.length = ret; > >- file_save("cldap_reply.dat", blob.data, blob.length); >- > asn1_load(&data, blob); > asn1_start_tag(&data, ASN1_SEQUENCE(0)); > asn1_read_Integer(&data, &i1); >@@ -196,8 +240,6 @@ > return -1; > } > >- file_save("cldap_reply_core.dat", os3.data, os3.length); >- > p = os3.data; > > reply->type = IVAL(p, 0); p += 4; >@@ -206,15 +248,25 @@ > memcpy(&reply->guid.info, p, GUID_SIZE); > p += GUID_SIZE; > >- p += pull_netlogon_string(&reply->forest, p); >- p += pull_netlogon_string(&reply->domain, p); >- p += pull_netlogon_string(&reply->hostname, p); >- p += pull_netlogon_string(&reply->netbios_domain, p); >- p += pull_netlogon_string(&reply->netbios_hostname, p); >- p += pull_netlogon_string(&reply->user_name, p); >- p += pull_netlogon_string(&reply->site_name, p); >+ p += pull_netlogon_string(reply->forest, p, os3.data); >+ p += pull_netlogon_string(reply->unk0, p, os3.data); >+ p += pull_netlogon_string(reply->domain, p, os3.data); >+ p += pull_netlogon_string(reply->hostname, p, os3.data); >+ p += pull_netlogon_string(reply->netbios_domain, p, os3.data); >+ p += pull_netlogon_string(reply->unk1, p, os3.data); >+ p += pull_netlogon_string(reply->netbios_hostname, p, os3.data); >+ p += pull_netlogon_string(reply->unk2, p, os3.data); >+ >+ if (reply->type == SAMLOGON_AD_R) { >+ p += pull_netlogon_string(reply->user_name, p, os3.data); >+ } else { >+ *reply->user_name = 0; >+ } > >- p += pull_netlogon_string(&reply->unk0, p); >+ p += pull_netlogon_string(reply->unk3, p, os3.data); >+ p += pull_netlogon_string(reply->site_name, p, os3.data); >+ p += pull_netlogon_string(reply->unk4, p, os3.data); >+ p += pull_netlogon_string(reply->site_name_2, p, os3.data); > > reply->version = IVAL(p, 0); > reply->lmnt_token = SVAL(p, 4); >@@ -229,52 +281,6 @@ > } > > /* >- free a netlogon string >-*/ >-static void netlogon_string_free(struct netlogon_string *str) >-{ >- unsigned int i; >- >- for (i = 0; i < str->comp_len; ++i) { >- SAFE_FREE(str->component[i]); >- } >- SAFE_FREE(str->component); >-} >- >-/* >- free a cldap reply packet >-*/ >-static void cldap_reply_free(struct cldap_netlogon_reply *reply) >-{ >- netlogon_string_free(&reply->forest); >- netlogon_string_free(&reply->domain); >- netlogon_string_free(&reply->hostname); >- netlogon_string_free(&reply->netbios_domain); >- netlogon_string_free(&reply->netbios_hostname); >- netlogon_string_free(&reply->user_name); >- netlogon_string_free(&reply->site_name); >- netlogon_string_free(&reply->unk0); >-} >- >-static void d_print_netlogon_string(const char *label, >- struct netlogon_string *str) >-{ >- unsigned int i; >- >- if (str->comp_len) { >- d_printf("%s", label); >- if (str->extra_flag) { >- d_printf("[%d]", str->extra_flag); >- } >- d_printf(": "); >- for (i = 0; i < str->comp_len; ++i) { >- d_printf("%s%s", (i ? "." : ""), str->component[i]); >- } >- d_printf("\n"); >- } >-} >- >-/* > do a cldap netlogon query > */ > int ads_cldap_netlogon(ADS_STRUCT *ads) >@@ -289,6 +295,7 @@ > inet_ntoa(ads->ldap_ip), > ads->ldap_port); > return -1; >+ > } > > ret = send_cldap_netlogon(sock, ads->config.realm, global_myname(), 6); >@@ -305,7 +312,18 @@ > d_printf("Information for Domain Controller: %s\n\n", > ads->config.ldap_server_name); > >- d_printf("Response Type: 0x%x\n", reply.type); >+ d_printf("Response Type: "); >+ switch (reply.type) { >+ case SAMLOGON_AD_UNK_R: >+ d_printf("SAMLOGON\n"); >+ break; >+ case SAMLOGON_AD_R: >+ d_printf("SAMLOGON_USER\n"); >+ break; >+ default: >+ d_printf("0x%x\n", reply.type); >+ break; >+ } > d_printf("GUID: "); > print_guid(&reply.guid); > d_printf("Flags:\n" >@@ -330,23 +348,27 @@ > (reply.flags & ADS_GOOD_TIMESERV) ? "yes" : "no", > (reply.flags & ADS_NDNC) ? "yes" : "no"); > >- d_print_netlogon_string("Forest", &reply.forest); >- d_print_netlogon_string("Domain", &reply.domain); >- d_print_netlogon_string("Hostname", &reply.hostname); >- >- d_print_netlogon_string("Pre-Win2k Domain", &reply.netbios_domain); >- d_print_netlogon_string("Pre-Win2k Hostname", &reply.netbios_hostname); >- >- d_print_netlogon_string("User name", &reply.user_name); >- d_print_netlogon_string("Site Name", &reply.site_name); >- d_print_netlogon_string("Unknown Field", &reply.unk0); >+ printf("Forest:\t\t\t%s\n", reply.forest); >+ if (*reply.unk0) printf("Unk0:\t\t\t%s\n", reply.unk0); >+ printf("Domain:\t\t\t%s\n", reply.domain); >+ printf("Domain Controller:\t%s\n", reply.hostname); >+ >+ printf("Pre-Win2k Domain:\t%s\n", reply.netbios_domain); >+ if (*reply.unk1) printf("Unk1:\t\t\t%s\n", reply.unk1); >+ printf("Pre-Win2k Hostname:\t%s\n", reply.netbios_hostname); >+ >+ if (*reply.unk2) printf("Unk2:\t\t\t%s\n", reply.unk2); >+ if (*reply.user_name) printf("User name:\t%s\n", reply.user_name); >+ >+ if (*reply.unk3) printf("Unk3:\t\t\t%s\n", reply.unk3); >+ printf("Site Name:\t\t%s\n", reply.site_name); >+ if (*reply.unk4) printf("Unk4:\t\t\t%s\n", reply.unk4); >+ printf("Site Name (2):\t\t%s\n", reply.site_name_2); > > d_printf("NT Version: %d\n", reply.version); > d_printf("LMNT Token: %.2x\n", reply.lmnt_token); > d_printf("LM20 Token: %.2x\n", reply.lm20_token); > >- cldap_reply_free(&reply); >- > return ret; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 96
: 10