diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-04-14 02:36:30 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:11:32 -0500 |
commit | 8d0a36366c741d0ae9302f1ac8cc6894033be687 (patch) | |
tree | 34a19b847efc4865c7534a78ca7e862de4401deb /source4/libcli/nbt | |
parent | 6f036daaa4a3f8c73512a7549a399e9b0f1f2758 (diff) | |
download | samba-8d0a36366c741d0ae9302f1ac8cc6894033be687.tar.gz samba-8d0a36366c741d0ae9302f1ac8cc6894033be687.tar.bz2 samba-8d0a36366c741d0ae9302f1ac8cc6894033be687.zip |
r6331: added IDL and test suite for the ADS style response to a datagram netlogon query.
Note that this response is almost identical to the CLDAP netlogon
response, so adding that will now be quite easy.
(This used to be commit 1ea4ed4ad1d9336f8288283688fa2d7bebfa533c)
Diffstat (limited to 'source4/libcli/nbt')
-rw-r--r-- | source4/libcli/nbt/nbtname.c | 206 |
1 files changed, 128 insertions, 78 deletions
diff --git a/source4/libcli/nbt/nbtname.c b/source4/libcli/nbt/nbtname.c index 12b8884e2d..f7d19d11cf 100644 --- a/source4/libcli/nbt/nbtname.c +++ b/source4/libcli/nbt/nbtname.c @@ -32,7 +32,15 @@ #define MAX_COMPONENTS 10 /* - pull one component of a compressed name + print a nbt string +*/ +void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s) +{ + return ndr_print_string(ndr, name, s); +} + +/* + pull one component of a nbt_string */ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, uint32_t *offset, uint32_t *max_offset) @@ -80,6 +88,97 @@ static NTSTATUS ndr_pull_component(struct ndr_pull *ndr, uint8_t **component, } /* + pull a nbt_string from the wire +*/ +NTSTATUS ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s) +{ + NTSTATUS status; + uint32_t offset = ndr->offset; + uint32_t max_offset = offset; + unsigned num_components; + char *name; + + if (!(ndr_flags & NDR_SCALARS)) { + return NT_STATUS_OK; + } + + name = NULL; + + /* break up name into a list of components */ + for (num_components=0;num_components<MAX_COMPONENTS;num_components++) { + uint8_t *component; + status = ndr_pull_component(ndr, &component, &offset, &max_offset); + NT_STATUS_NOT_OK_RETURN(status); + if (component == NULL) break; + if (name) { + name = talloc_asprintf_append(name, ".%s", component); + NT_STATUS_HAVE_NO_MEMORY(name); + } else { + name = component; + } + } + if (num_components == MAX_COMPONENTS) { + return NT_STATUS_BAD_NETWORK_NAME; + } + if (num_components == 0) { + name = talloc_strdup(ndr, ""); + NT_STATUS_HAVE_NO_MEMORY(name); + } + + (*s) = name; + ndr->offset = max_offset; + + return NT_STATUS_OK; +} + +/* + push a nbt string to the wire +*/ +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; + } + + fullname = talloc_strdup(ndr, ""); + NT_STATUS_HAVE_NO_MEMORY(fullname); + + 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) { + talloc_free(fullname); + return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i); + } + } + + NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen)); + + talloc_free(fullname); + + return NT_STATUS_OK; +} + + +/* decompress a 'compressed' name component */ static NTSTATUS decompress_name(char *name, enum nbt_name_type *type) @@ -151,57 +250,49 @@ static uint8_t *compress_name(TALLOC_CTX *mem_ctx, return cname; } + /* pull a nbt name from the wire */ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r) { NTSTATUS status; - uint_t num_components; - uint32_t offset = ndr->offset; - uint32_t max_offset = offset; - uint8_t *components[MAX_COMPONENTS]; - int i; uint8_t *scope; + char *cname; + const char *s; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - /* break up name into a list of components */ - for (num_components=0;num_components<MAX_COMPONENTS;num_components++) { - status = ndr_pull_component(ndr, &components[num_components], - &offset, &max_offset); - NT_STATUS_NOT_OK_RETURN(status); - if (components[num_components] == NULL) break; - } - if (num_components == MAX_COMPONENTS || - num_components == 0) { - return NT_STATUS_BAD_NETWORK_NAME; + status = ndr_pull_nbt_string(ndr, ndr_flags, &s); + NT_STATUS_NOT_OK_RETURN(status); + + scope = strchr(s, '.'); + if (scope) { + *scope = 0; + r->scope = talloc_strdup(ndr, scope+1); + NT_STATUS_HAVE_NO_MEMORY(r->scope); + } else { + r->scope = NULL; } - ndr->offset = max_offset; + cname = discard_const_p(char, s); /* the first component is limited to 16 bytes in the DOS charset, which is 32 in the 'compressed' form */ - if (strlen(components[0]) > 32) { + if (strlen(cname) > 32) { return NT_STATUS_BAD_NETWORK_NAME; } /* decompress the first component */ - status = decompress_name(components[0], &r->type); + status = decompress_name(cname, &r->type); NT_STATUS_NOT_OK_RETURN(status); - r->name = components[0]; - - /* combine the remaining components into the scope */ - scope = components[1]; - for (i=2;i<num_components;i++) { - scope = talloc_asprintf_append(scope, ".%s", components[i]); - NT_STATUS_HAVE_NO_MEMORY(scope); - } + r->name = talloc_strdup(ndr, cname); + NT_STATUS_HAVE_NO_MEMORY(r->name); - r->scope = scope; + talloc_free(cname); return NT_STATUS_OK; } @@ -211,69 +302,28 @@ NTSTATUS ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name */ NTSTATUS ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, struct nbt_name *r) { - uint_t num_components; - uint8_t *components[MAX_COMPONENTS]; - char *dscope=NULL, *p; uint8_t *cname, *fullname; - int i; - int fulllen; + NTSTATUS status; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } - if (r->scope) { - dscope = talloc_strdup(ndr, r->scope); - NT_STATUS_HAVE_NO_MEMORY(dscope); - } - cname = compress_name(ndr, r->name, r->type); NT_STATUS_HAVE_NO_MEMORY(cname); - /* form the base components */ - components[0] = cname; - num_components = 1; - - while (dscope && (p=strchr(dscope, '.')) && - num_components < MAX_COMPONENTS) { - *p = 0; - components[num_components] = dscope; - dscope = p+1; - num_components++; - } - if (dscope && num_components < MAX_COMPONENTS) { - components[num_components++] = dscope; - } - if (num_components == MAX_COMPONENTS) { - return NT_STATUS_BAD_NETWORK_NAME; - } - - fullname = talloc_asprintf(ndr, "%c%s", (unsigned char)strlen(cname), cname); - NT_STATUS_HAVE_NO_MEMORY(fullname); - - for (i=1;i<num_components;i++) { - fullname = talloc_asprintf_append(fullname, "%c%s", - (unsigned char)strlen(components[i]), components[i]); + if (r->scope) { + fullname = talloc_asprintf(ndr, "%s.%s", cname, r->scope); NT_STATUS_HAVE_NO_MEMORY(fullname); + talloc_free(cname); + } else { + fullname = cname; } - - /* 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) { - talloc_free(fullname); - return ndr_push_uint16(ndr, NDR_SCALARS, 0xC000 | i); - } - } - - NDR_CHECK(ndr_push_bytes(ndr, fullname, fulllen)); - + + status = ndr_push_nbt_string(ndr, ndr_flags, fullname); talloc_free(fullname); - return NT_STATUS_OK; + return status; } |