2 Unix SMB/CIFS implementation.
4 CLDAP server structures
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* parser auto-generated by pidl, then hand-modified by abartlet */
26 #include "../libcli/nbt/libnbt.h"
27 #include "../libcli/netlogon/netlogon.h"
29 /* don't allow an unlimited number of name components */
30 #define MAX_COMPONENTS 128
35 _PUBLIC_
void ndr_print_nbt_string(struct ndr_print
*ndr
, const char *name
, const char *s
)
37 ndr_print_string(ndr
, name
, s
);
41 pull one component of a nbt_string
43 static enum ndr_err_code
ndr_pull_component(struct ndr_pull
*ndr
,
49 unsigned int loops
= 0;
51 if (*offset
>= ndr
->data_size
) {
52 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
53 "BAD NBT NAME component");
55 len
= ndr
->data
[*offset
];
58 *max_offset
= MAX(*max_offset
, *offset
);
60 return NDR_ERR_SUCCESS
;
62 if ((len
& 0xC0) == 0xC0) {
63 /* its a label pointer */
64 if (1 + *offset
>= ndr
->data_size
) {
65 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
66 "BAD NBT NAME component");
68 *max_offset
= MAX(*max_offset
, *offset
+ 2);
69 *offset
= ((len
&0x3F)<<8) | ndr
->data
[1 + *offset
];
70 *max_offset
= MAX(*max_offset
, *offset
);
74 if ((len
& 0xC0) != 0) {
75 /* its a reserved length field */
76 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
77 "BAD NBT NAME component");
79 if (*offset
+ len
+ 1 > ndr
->data_size
) {
80 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
81 "BAD NBT NAME component");
83 *component
= (uint8_t*)talloc_strndup(
85 (const char *)&ndr
->data
[1 + *offset
], len
);
86 NDR_ERR_HAVE_NO_MEMORY(*component
);
88 *max_offset
= MAX(*max_offset
, *offset
);
89 return NDR_ERR_SUCCESS
;
92 /* too many pointers */
93 return ndr_pull_error(ndr
, NDR_ERR_STRING
, "BAD NBT NAME component");
97 pull a nbt_string from the wire
99 _PUBLIC_
enum ndr_err_code
ndr_pull_nbt_string(struct ndr_pull
*ndr
, int ndr_flags
, const char **s
)
101 uint32_t offset
= ndr
->offset
;
102 uint32_t max_offset
= offset
;
103 unsigned num_components
;
106 if (!(ndr_flags
& NDR_SCALARS
)) {
107 return NDR_ERR_SUCCESS
;
112 /* break up name into a list of components */
113 for (num_components
=0;num_components
<MAX_COMPONENTS
;num_components
++) {
114 uint8_t *component
= NULL
;
115 NDR_CHECK(ndr_pull_component(ndr
, &component
, &offset
, &max_offset
));
116 if (component
== NULL
) break;
118 name
= talloc_asprintf_append_buffer(name
, ".%s", component
);
119 NDR_ERR_HAVE_NO_MEMORY(name
);
121 name
= (char *)component
;
124 if (num_components
== MAX_COMPONENTS
) {
125 return ndr_pull_error(ndr
, NDR_ERR_STRING
,
126 "BAD NBT NAME too many components");
128 if (num_components
== 0) {
129 name
= talloc_strdup(ndr
->current_mem_ctx
, "");
130 NDR_ERR_HAVE_NO_MEMORY(name
);
134 ndr
->offset
= max_offset
;
136 return NDR_ERR_SUCCESS
;
140 push a nbt string to the wire
142 _PUBLIC_
enum ndr_err_code
ndr_push_nbt_string(struct ndr_push
*ndr
, int ndr_flags
, const char *s
)
144 if (!(ndr_flags
& NDR_SCALARS
)) {
145 return NDR_ERR_SUCCESS
;
149 enum ndr_err_code ndr_err
;
154 /* see if we have pushed the remaing string allready,
155 * if so we use a label pointer to this string
157 ndr_err
= ndr_token_retrieve_cmp_fn(&ndr
->nbt_string_list
, s
, &offset
, (comparison_fn_t
)strcmp
, false);
158 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
161 if (offset
> 0x3FFF) {
162 return ndr_push_error(ndr
, NDR_ERR_STRING
,
163 "offset for nbt string label pointer %u[%08X] > 0x00003FFF",
167 b
[0] = 0xC0 | (offset
>>8);
168 b
[1] = (offset
& 0xFF);
170 return ndr_push_bytes(ndr
, b
, 2);
173 complen
= strcspn(s
, ".");
175 /* we need to make sure the length fits into 6 bytes */
176 if (complen
> 0x3F) {
177 return ndr_push_error(ndr
, NDR_ERR_STRING
,
178 "component length %u[%08X] > 0x0000003F",
179 (unsigned)complen
, (unsigned)complen
);
182 if (s
[complen
] == '.' && s
[complen
+1] == '\0') {
186 compname
= talloc_asprintf(ndr
, "%c%*.*s",
187 (unsigned char)complen
,
188 (unsigned char)complen
,
189 (unsigned char)complen
, s
);
190 NDR_ERR_HAVE_NO_MEMORY(compname
);
192 /* remember the current componemt + the rest of the string
193 * so it can be reused later
195 NDR_CHECK(ndr_token_store(ndr
, &ndr
->nbt_string_list
, s
, ndr
->offset
));
197 /* push just this component into the blob */
198 NDR_CHECK(ndr_push_bytes(ndr
, (const uint8_t *)compname
, complen
+1));
199 talloc_free(compname
);
205 /* if we reach the end of the string and have pushed the last component
206 * without using a label pointer, we need to terminate the string
208 return ndr_push_bytes(ndr
, (const uint8_t *)"", 1);
212 /* Manually modified to handle the dom_sid being optional based on if it is present or all zero */
213 enum ndr_err_code
ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push
*ndr
, int ndr_flags
, const struct NETLOGON_SAM_LOGON_REQUEST
*r
)
215 if (ndr_flags
& NDR_SCALARS
) {
216 NDR_CHECK(ndr_push_align(ndr
, 4));
217 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->request_count
));
219 uint32_t _flags_save_string
= ndr
->flags
;
220 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
221 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->computer_name
));
222 ndr
->flags
= _flags_save_string
;
225 uint32_t _flags_save_string
= ndr
->flags
;
226 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
227 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->user_name
));
228 ndr
->flags
= _flags_save_string
;
231 uint32_t _flags_save_string
= ndr
->flags
;
232 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_NULLTERM
);
233 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->mailslot_name
));
234 ndr
->flags
= _flags_save_string
;
236 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, r
->acct_control
));
237 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
238 if (ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)) {
239 struct ndr_push
*_ndr_sid
;
240 uint32_t _flags_save_DATA_BLOB
= ndr
->flags
;
241 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_ALIGN4
);
242 NDR_CHECK(ndr_push_DATA_BLOB(ndr
, NDR_SCALARS
, r
->_pad
));
243 ndr
->flags
= _flags_save_DATA_BLOB
;
244 NDR_CHECK(ndr_push_subcontext_start(ndr
, &_ndr_sid
, 0, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
245 NDR_CHECK(ndr_push_dom_sid0(_ndr_sid
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sid
));
246 NDR_CHECK(ndr_push_subcontext_end(ndr
, _ndr_sid
, 0, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
248 NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, r
->nt_version
));
249 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lmnt_token
));
250 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lm20_token
));
252 if (ndr_flags
& NDR_BUFFERS
) {
254 return NDR_ERR_SUCCESS
;
257 /* Manually modified to handle the dom_sid being optional based on if it is present (size is non-zero) or not */
258 enum ndr_err_code
ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull
*ndr
, int ndr_flags
, struct NETLOGON_SAM_LOGON_REQUEST
*r
)
260 if (ndr_flags
& NDR_SCALARS
) {
261 NDR_CHECK(ndr_pull_align(ndr
, 4));
262 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->request_count
));
264 uint32_t _flags_save_string
= ndr
->flags
;
265 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
266 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->computer_name
));
267 ndr
->flags
= _flags_save_string
;
270 uint32_t _flags_save_string
= ndr
->flags
;
271 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
272 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->user_name
));
273 ndr
->flags
= _flags_save_string
;
276 uint32_t _flags_save_string
= ndr
->flags
;
277 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_NULLTERM
);
278 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->mailslot_name
));
279 ndr
->flags
= _flags_save_string
;
281 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &r
->acct_control
));
282 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &r
->sid_size
));
284 uint32_t _flags_save_DATA_BLOB
= ndr
->flags
;
285 struct ndr_pull
*_ndr_sid
;
286 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_ALIGN4
);
287 NDR_CHECK(ndr_pull_DATA_BLOB(ndr
, NDR_SCALARS
, &r
->_pad
));
288 ndr
->flags
= _flags_save_DATA_BLOB
;
289 NDR_CHECK(ndr_pull_subcontext_start(ndr
, &_ndr_sid
, 0, r
->sid_size
));
290 NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sid
));
291 NDR_CHECK(ndr_pull_subcontext_end(ndr
, _ndr_sid
, 0, r
->sid_size
));
295 NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, &r
->nt_version
));
296 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lmnt_token
));
297 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lm20_token
));
299 if (ndr_flags
& NDR_BUFFERS
) {
301 return NDR_ERR_SUCCESS
;
304 /* Manually modified to only push some parts of the structure if certain flags are set */
305 enum ndr_err_code
ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_push
*ndr
, int ndr_flags
, const struct NETLOGON_SAM_LOGON_RESPONSE_EX
*r
)
308 uint32_t _flags_save_STRUCT
= ndr
->flags
;
309 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_NOALIGN
);
310 if (ndr_flags
& NDR_SCALARS
) {
311 NDR_CHECK(ndr_push_align(ndr
, 4));
312 NDR_CHECK(ndr_push_netlogon_command(ndr
, NDR_SCALARS
, r
->command
));
313 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->sbz
));
314 NDR_CHECK(ndr_push_nbt_server_type(ndr
, NDR_SCALARS
, r
->server_type
));
315 NDR_CHECK(ndr_push_GUID(ndr
, NDR_SCALARS
, &r
->domain_uuid
));
316 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->forest
));
317 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->dns_domain
));
318 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->pdc_dns_name
));
319 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->domain_name
));
320 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->pdc_name
));
321 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->user_name
));
322 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->server_site
));
323 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->client_site
));
324 if (r
->nt_version
& NETLOGON_NT_VERSION_5EX_WITH_IP
) {
325 NDR_CHECK(ndr_push_uint8(ndr
, NDR_SCALARS
, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
327 struct ndr_push
*_ndr_sockaddr
;
328 NDR_CHECK(ndr_push_subcontext_start(ndr
, &_ndr_sockaddr
, 0, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
329 NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sockaddr
));
330 NDR_CHECK(ndr_push_subcontext_end(ndr
, _ndr_sockaddr
, 0, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
333 if (r
->nt_version
& NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
) {
334 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->next_closest_site
));
336 NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, r
->nt_version
));
337 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lmnt_token
));
338 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lm20_token
));
340 if (ndr_flags
& NDR_BUFFERS
) {
341 NDR_CHECK(ndr_push_GUID(ndr
, NDR_BUFFERS
, &r
->domain_uuid
));
343 ndr
->flags
= _flags_save_STRUCT
;
345 return NDR_ERR_SUCCESS
;
348 /* Manually modified to only pull some parts of the structure if certain flags provided */
349 enum ndr_err_code
ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(struct ndr_pull
*ndr
, int ndr_flags
, struct NETLOGON_SAM_LOGON_RESPONSE_EX
*r
,
350 uint32_t nt_version_flags
)
353 uint32_t _flags_save_STRUCT
= ndr
->flags
;
355 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_NOALIGN
);
356 if (ndr_flags
& NDR_SCALARS
) {
357 NDR_CHECK(ndr_pull_align(ndr
, 4));
358 NDR_CHECK(ndr_pull_netlogon_command(ndr
, NDR_SCALARS
, &r
->command
));
359 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->sbz
));
360 NDR_CHECK(ndr_pull_nbt_server_type(ndr
, NDR_SCALARS
, &r
->server_type
));
361 NDR_CHECK(ndr_pull_GUID(ndr
, NDR_SCALARS
, &r
->domain_uuid
));
362 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->forest
));
363 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->dns_domain
));
364 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->pdc_dns_name
));
365 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->domain_name
));
366 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->pdc_name
));
367 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->user_name
));
368 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->server_site
));
369 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->client_site
));
370 if (nt_version_flags
& NETLOGON_NT_VERSION_5EX_WITH_IP
) {
371 NDR_CHECK(ndr_pull_uint8(ndr
, NDR_SCALARS
, &r
->sockaddr_size
));
373 struct ndr_pull
*_ndr_sockaddr
;
374 NDR_CHECK(ndr_pull_subcontext_start(ndr
, &_ndr_sockaddr
, 0, r
->sockaddr_size
));
375 NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sockaddr
));
376 NDR_CHECK(ndr_pull_subcontext_end(ndr
, _ndr_sockaddr
, 0, r
->sockaddr_size
));
379 if (nt_version_flags
& NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
) {
380 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->next_closest_site
));
382 NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, &r
->nt_version
));
383 if (r
->nt_version
!= nt_version_flags
) {
384 return NDR_ERR_VALIDATE
;
386 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lmnt_token
));
387 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lm20_token
));
389 if (ndr_flags
& NDR_BUFFERS
) {
390 NDR_CHECK(ndr_pull_GUID(ndr
, NDR_BUFFERS
, &r
->domain_uuid
));
392 ndr
->flags
= _flags_save_STRUCT
;
394 return NDR_ERR_SUCCESS
;
397 _PUBLIC_
enum ndr_err_code
ndr_push_netlogon_samlogon_response(struct ndr_push
*ndr
, int ndr_flags
, const struct netlogon_samlogon_response
*r
)
399 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
400 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40(
401 ndr
, ndr_flags
, &r
->data
.nt4
));
402 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
403 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
404 ndr
, ndr_flags
, &r
->data
.nt5_ex
));
405 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
406 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE(
407 ndr
, ndr_flags
, &r
->data
.nt5
));
409 return NDR_ERR_BAD_SWITCH
;
412 return NDR_ERR_SUCCESS
;
415 _PUBLIC_
enum ndr_err_code
ndr_pull_netlogon_samlogon_response(struct ndr_pull
*ndr
, int ndr_flags
, struct netlogon_samlogon_response
*r
)
417 if (ndr
->data_size
< 8) {
418 return NDR_ERR_BUFSIZE
;
422 if (SVAL(ndr
->data
, ndr
->data_size
- 4) != 0xffff) {
423 return NDR_ERR_TOKEN
;
426 if (SVAL(ndr
->data
, ndr
->data_size
- 2) != 0xffff) {
427 return NDR_ERR_TOKEN
;
430 r
->ntver
= IVAL(ndr
->data
, ndr
->data_size
- 8);
432 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
433 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40(
434 ndr
, ndr_flags
, &r
->data
.nt4
));
435 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
436 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
437 ndr
, ndr_flags
, &r
->data
.nt5_ex
, r
->ntver
));
438 if (ndr
->offset
< ndr
->data_size
) {
439 return ndr_pull_error(ndr
, NDR_ERR_UNREAD_BYTES
,
440 "not all bytes consumed ofs[%u] size[%u]",
441 ndr
->offset
, ndr
->data_size
);
443 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
444 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE(
445 ndr
, ndr_flags
, &r
->data
.nt5
));
447 return NDR_ERR_BAD_SWITCH
;
450 return NDR_ERR_SUCCESS
;