diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-12-21 11:59:54 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-12-21 03:26:26 +0100 |
commit | 4820c97e9ea00e73f3188f9834a03913ed74df80 (patch) | |
tree | 08a294fda3ec11a7ff68b840cea495786c1deea8 /librpc/ndr | |
parent | 049a16c8ef475f6b327292d231022fd4c5aaddf1 (diff) | |
download | samba-4820c97e9ea00e73f3188f9834a03913ed74df80.tar.gz samba-4820c97e9ea00e73f3188f9834a03913ed74df80.tar.bz2 samba-4820c97e9ea00e73f3188f9834a03913ed74df80.zip |
dns: fixed the padding for dnsp_name fields in LDAP
all names are NUL terminated, but may have additional padding as well
Autobuild-User: Andrew Tridgell <tridge@samba.org>
Autobuild-Date: Tue Dec 21 03:26:26 CET 2010 on sn-devel-104
Diffstat (limited to 'librpc/ndr')
-rw-r--r-- | librpc/ndr/ndr_dnsp.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/librpc/ndr/ndr_dnsp.c b/librpc/ndr/ndr_dnsp.c index 77c2366d14..ae78425c55 100644 --- a/librpc/ndr/ndr_dnsp.c +++ b/librpc/ndr/ndr_dnsp.c @@ -36,14 +36,16 @@ _PUBLIC_ void ndr_print_dnsp_name(struct ndr_print *ndr, const char *name, */ _PUBLIC_ enum ndr_err_code ndr_pull_dnsp_name(struct ndr_pull *ndr, int ndr_flags, const char **name) { - uint8_t len, count, final; + uint8_t len, count, termination; int i; - uint32_t total_len; + uint32_t total_len, raw_offset; char *ret; NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &len)); NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &count)); + raw_offset = ndr->offset; + ret = talloc_strdup(ndr->current_mem_ctx, ""); if (!ret) { return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp"); @@ -68,7 +70,19 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dnsp_name(struct ndr_pull *ndr, int ndr_flag ret[newlen-1] = 0; total_len = newlen; } - NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &final)); + NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &termination)); + if (termination != 0) { + return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp - not NUL terminated"); + } + if (ndr->offset > raw_offset + len) { + return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp - overrun by %u bytes", + ndr->offset - (raw_offset + len)); + } + /* there could be additional pad bytes */ + while (ndr->offset < raw_offset + len) { + uint8_t pad; + NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &pad)); + } (*name) = ret; return NDR_ERR_SUCCESS; } @@ -81,7 +95,7 @@ enum ndr_err_code ndr_push_dnsp_name(struct ndr_push *ndr, int ndr_flags, const for (count=i=0; name[i]; i++) { if (name[i] == '.') count++; } - total_len = strlen(name) + 1; + total_len = strlen(name) + 1 + 1; if (total_len > 255 || count > 255) { return ndr_push_error(ndr, NDR_ERR_BUFSIZE, "dns_name of length %d larger than 255", total_len); |