Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Manually parsed structures found in DNSP
5 :
6 : Copyright (C) Andrew Tridgell 2010
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "librpc/gen_ndr/ndr_dnsp.h"
24 :
25 : /*
26 : print a dnsp_name
27 : */
28 28 : _PUBLIC_ void ndr_print_dnsp_name(struct ndr_print *ndr, const char *name,
29 : const char *dns_name)
30 : {
31 28 : ndr->print(ndr, "%-25s: %s", name, dns_name);
32 28 : }
33 :
34 : /*
35 : pull a dnsp_name
36 : */
37 27905 : _PUBLIC_ enum ndr_err_code ndr_pull_dnsp_name(struct ndr_pull *ndr, ndr_flags_type ndr_flags, const char **name)
38 : {
39 38 : uint8_t len, count, termination;
40 38 : int i;
41 38 : uint32_t total_len, raw_offset;
42 38 : char *ret;
43 :
44 27905 : NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &len));
45 27905 : NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &count));
46 :
47 27905 : raw_offset = ndr->offset;
48 :
49 27905 : ret = talloc_strdup(ndr->current_mem_ctx, "");
50 27905 : if (!ret) {
51 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_name");
52 : }
53 27867 : total_len = 1;
54 :
55 157724 : for (i=0; i<count; i++) {
56 144 : uint8_t sublen, newlen;
57 129819 : NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &sublen));
58 129819 : newlen = total_len + sublen;
59 129819 : if (newlen < total_len) {
60 0 : return ndr_pull_error(ndr, NDR_ERR_RANGE,
61 : "Failed to pull dnsp_name");
62 : }
63 129819 : if (i != count-1) {
64 102403 : if (newlen == UINT8_MAX) {
65 0 : return ndr_pull_error(
66 : ndr, NDR_ERR_RANGE,
67 : "Failed to pull dnsp_name");
68 : }
69 102403 : newlen++; /* for the '.' */
70 : }
71 129819 : ret = talloc_realloc(ndr->current_mem_ctx, ret, char, newlen);
72 129819 : if (!ret) {
73 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_name");
74 : }
75 129819 : NDR_CHECK(ndr_pull_bytes(ndr, (uint8_t *)&ret[total_len-1], sublen));
76 129819 : if (i != count-1) {
77 102403 : ret[newlen-2] = '.';
78 : }
79 129819 : ret[newlen-1] = 0;
80 129819 : total_len = newlen;
81 : }
82 27905 : NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &termination));
83 27905 : if (termination != 0) {
84 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_name - not NUL terminated");
85 : }
86 27905 : if (ndr->offset > raw_offset + len) {
87 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_name - overrun by %"PRIu32" bytes",
88 : ndr->offset - (raw_offset + len));
89 : }
90 : /* there could be additional pad bytes */
91 27905 : while (ndr->offset < raw_offset + len) {
92 0 : uint8_t pad;
93 0 : NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &pad));
94 : }
95 27905 : (*name) = ret;
96 27905 : return NDR_ERR_SUCCESS;
97 : }
98 :
99 34624 : enum ndr_err_code ndr_push_dnsp_name(struct ndr_push *ndr, ndr_flags_type ndr_flags, const char *name)
100 : {
101 2326 : int count, total_len, i;
102 :
103 : /* count the dots */
104 978510 : for (count=i=0; name[i]; i++) {
105 943886 : if (name[i] == '.') count++;
106 : }
107 34624 : total_len = strlen(name) + 1;
108 :
109 : /*
110 : * cope with names ending in '.'
111 : */
112 34624 : if (name[0] == '\0') {
113 : /*
114 : * Don't access name[-1] for the "" input, which has
115 : * the same meaning as a lone '.'.
116 : *
117 : * This allows a round-trip of a dnsRecord from
118 : * Windows of a MX record of '.'
119 : */
120 34556 : } else if (name[strlen(name)-1] != '.') {
121 34510 : total_len++;
122 34510 : count++;
123 : }
124 34624 : if (total_len > 255 || count > 255) {
125 0 : return ndr_push_error(ndr, NDR_ERR_BUFSIZE,
126 : "dns_name of length %d larger than 255", total_len);
127 : }
128 34624 : NDR_CHECK(ndr_push_uint8(ndr, ndr_flags, (uint8_t)total_len));
129 34624 : NDR_CHECK(ndr_push_uint8(ndr, ndr_flags, (uint8_t)count));
130 184736 : for (i=0; i<count; i++) {
131 150112 : const char *p = strchr(name, '.');
132 150112 : size_t sublen = p?(p-name):strlen(name);
133 150112 : NDR_CHECK(ndr_push_uint8(ndr, ndr_flags, (uint8_t)sublen));
134 150112 : NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)name, sublen));
135 150112 : name += sublen + 1;
136 : }
137 34624 : NDR_CHECK(ndr_push_uint8(ndr, ndr_flags, 0));
138 :
139 32298 : return NDR_ERR_SUCCESS;
140 : }
141 :
142 : /*
143 : print a dnsp_string
144 : */
145 0 : _PUBLIC_ void ndr_print_dnsp_string(struct ndr_print *ndr, const char *name,
146 : const char *dns_string)
147 : {
148 0 : ndr->print(ndr, "%-25s: %s", name, dns_string);
149 0 : }
150 :
151 : /*
152 : pull a dnsp_string
153 : */
154 11092 : _PUBLIC_ enum ndr_err_code ndr_pull_dnsp_string(struct ndr_pull *ndr, ndr_flags_type ndr_flags, const char **string)
155 : {
156 0 : uint8_t len;
157 0 : char *ret;
158 :
159 11092 : NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &len));
160 :
161 11092 : ret = talloc_zero_array(ndr->current_mem_ctx, char, len + 1);
162 11092 : if (!ret) {
163 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_string");
164 : }
165 11092 : NDR_CHECK(ndr_pull_bytes(ndr, (uint8_t *)ret, len));
166 :
167 11092 : (*string) = ret;
168 11092 : NDR_PULL_ALIGN(ndr, 1);
169 11092 : return NDR_ERR_SUCCESS;
170 : }
171 :
172 8694 : enum ndr_err_code ndr_push_dnsp_string(struct ndr_push *ndr, ndr_flags_type ndr_flags, const char *string)
173 : {
174 0 : int total_len;
175 8694 : total_len = strlen(string);
176 8694 : if (total_len > 255) {
177 0 : return ndr_push_error(ndr, NDR_ERR_BUFSIZE,
178 : "dns_name of length %d larger than 255", total_len);
179 : }
180 8694 : NDR_CHECK(ndr_push_uint8(ndr, ndr_flags, (uint8_t)total_len));
181 8694 : NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)string, total_len));
182 :
183 8694 : return NDR_ERR_SUCCESS;
184 : }
185 :
186 : /*
187 : * print a dnsp_string_list
188 : */
189 0 : _PUBLIC_ void ndr_print_dnsp_string_list(struct ndr_print *ndr, const char *name,
190 : const struct dnsp_string_list *list)
191 : {
192 0 : uint32_t i;
193 :
194 0 : ndr->no_newline = true;
195 0 : for (i=0; i<ndr->depth; i++) {
196 0 : ndr->print(ndr, " ");
197 : }
198 0 : ndr->print(ndr, "%-25s:", name);
199 0 : for (i=0; i<list->count; i++) {
200 0 : ndr->print(ndr, " \"%s\"", list->str[i]);
201 : }
202 0 : ndr->print(ndr, "\n");
203 0 : ndr->no_newline = false;
204 0 : }
205 :
206 : /*
207 : * pull a dnsp_string_list
208 : */
209 9450 : _PUBLIC_ enum ndr_err_code ndr_pull_dnsp_string_list(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct dnsp_string_list *list)
210 : {
211 9450 : list->count = 0;
212 9450 : list->str = talloc_array(ndr->current_mem_ctx, const char *,
213 : list->count);
214 9450 : if (! list->str) {
215 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_string_list");
216 : }
217 :
218 20542 : while (ndr->offset < ndr->data_size) {
219 11092 : list->str = talloc_realloc(ndr->current_mem_ctx, list->str,
220 : const char *, list->count+1);
221 11092 : if (! list->str) {
222 0 : return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Failed to pull dnsp_string_list");
223 : }
224 11092 : NDR_CHECK(ndr_pull_dnsp_string(ndr, ndr_flags, &list->str[list->count]));
225 11092 : list->count++;
226 : }
227 :
228 9450 : return NDR_ERR_SUCCESS;
229 : }
230 :
231 7383 : enum ndr_err_code ndr_push_dnsp_string_list(struct ndr_push *ndr, ndr_flags_type ndr_flags, const struct dnsp_string_list *list)
232 : {
233 0 : uint8_t i;
234 :
235 16077 : for (i=0; i<list->count; i++) {
236 8694 : NDR_CHECK(ndr_push_dnsp_string(ndr, ndr_flags, list->str[i]));
237 : }
238 7383 : return NDR_ERR_SUCCESS;
239 : }
240 :
241 1055 : enum ndr_err_code ndr_dnsp_string_list_copy(TALLOC_CTX *mem_ctx,
242 : const struct dnsp_string_list *src,
243 : struct dnsp_string_list *dst)
244 : {
245 0 : size_t i;
246 :
247 1055 : dst->count = 0;
248 1055 : dst->str = talloc_zero_array(mem_ctx, const char *, src->count);
249 1055 : if (dst->str == NULL) {
250 0 : return NDR_ERR_ALLOC;
251 : }
252 :
253 2269 : for (i = 0; i < src->count; i++) {
254 1214 : dst->str[i] = talloc_strdup(dst->str, src->str[i]);
255 1214 : if (dst->str[i] == NULL) {
256 0 : TALLOC_FREE(dst->str);
257 0 : return NDR_ERR_ALLOC;
258 : }
259 : }
260 :
261 1055 : dst->count = src->count;
262 1055 : return NDR_ERR_SUCCESS;
263 : }
|