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 10
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 compname
= talloc_asprintf(ndr
, "%c%*.*s",
183 (unsigned char)complen
,
184 (unsigned char)complen
,
185 (unsigned char)complen
, s
);
186 NDR_ERR_HAVE_NO_MEMORY(compname
);
188 /* remember the current componemt + the rest of the string
189 * so it can be reused later
191 NDR_CHECK(ndr_token_store(ndr
, &ndr
->nbt_string_list
, s
, ndr
->offset
));
193 /* push just this component into the blob */
194 NDR_CHECK(ndr_push_bytes(ndr
, (const uint8_t *)compname
, complen
+1));
195 talloc_free(compname
);
201 /* if we reach the end of the string and have pushed the last component
202 * without using a label pointer, we need to terminate the string
204 return ndr_push_bytes(ndr
, (const uint8_t *)"", 1);
208 /* Manually modified to handle the dom_sid being optional based on if it is present or all zero */
209 enum ndr_err_code
ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push
*ndr
, int ndr_flags
, const struct NETLOGON_SAM_LOGON_REQUEST
*r
)
211 if (ndr_flags
& NDR_SCALARS
) {
212 NDR_CHECK(ndr_push_align(ndr
, 4));
213 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->request_count
));
215 uint32_t _flags_save_string
= ndr
->flags
;
216 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
217 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->computer_name
));
218 ndr
->flags
= _flags_save_string
;
221 uint32_t _flags_save_string
= ndr
->flags
;
222 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
223 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->user_name
));
224 ndr
->flags
= _flags_save_string
;
227 uint32_t _flags_save_string
= ndr
->flags
;
228 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_NULLTERM
);
229 NDR_CHECK(ndr_push_string(ndr
, NDR_SCALARS
, r
->mailslot_name
));
230 ndr
->flags
= _flags_save_string
;
232 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, r
->acct_control
));
233 NDR_CHECK(ndr_push_uint32(ndr
, NDR_SCALARS
, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
234 if (ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)) {
235 struct ndr_push
*_ndr_sid
;
236 uint32_t _flags_save_DATA_BLOB
= ndr
->flags
;
237 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_ALIGN4
);
238 NDR_CHECK(ndr_push_DATA_BLOB(ndr
, NDR_SCALARS
, r
->_pad
));
239 ndr
->flags
= _flags_save_DATA_BLOB
;
240 NDR_CHECK(ndr_push_subcontext_start(ndr
, &_ndr_sid
, 0, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
241 NDR_CHECK(ndr_push_dom_sid0(_ndr_sid
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sid
));
242 NDR_CHECK(ndr_push_subcontext_end(ndr
, _ndr_sid
, 0, ndr_size_dom_sid0(&r
->sid
, ndr
->flags
)));
244 NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, r
->nt_version
));
245 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lmnt_token
));
246 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lm20_token
));
248 if (ndr_flags
& NDR_BUFFERS
) {
250 return NDR_ERR_SUCCESS
;
253 /* Manually modified to handle the dom_sid being optional based on if it is present (size is non-zero) or not */
254 enum ndr_err_code
ndr_pull_NETLOGON_SAM_LOGON_REQUEST(struct ndr_pull
*ndr
, int ndr_flags
, struct NETLOGON_SAM_LOGON_REQUEST
*r
)
256 if (ndr_flags
& NDR_SCALARS
) {
257 NDR_CHECK(ndr_pull_align(ndr
, 4));
258 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->request_count
));
260 uint32_t _flags_save_string
= ndr
->flags
;
261 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
262 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->computer_name
));
263 ndr
->flags
= _flags_save_string
;
266 uint32_t _flags_save_string
= ndr
->flags
;
267 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_NULLTERM
);
268 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->user_name
));
269 ndr
->flags
= _flags_save_string
;
272 uint32_t _flags_save_string
= ndr
->flags
;
273 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_STR_ASCII
|LIBNDR_FLAG_STR_NULLTERM
);
274 NDR_CHECK(ndr_pull_string(ndr
, NDR_SCALARS
, &r
->mailslot_name
));
275 ndr
->flags
= _flags_save_string
;
277 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &r
->acct_control
));
278 NDR_CHECK(ndr_pull_uint32(ndr
, NDR_SCALARS
, &r
->sid_size
));
280 uint32_t _flags_save_DATA_BLOB
= ndr
->flags
;
281 struct ndr_pull
*_ndr_sid
;
282 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_ALIGN4
);
283 NDR_CHECK(ndr_pull_DATA_BLOB(ndr
, NDR_SCALARS
, &r
->_pad
));
284 ndr
->flags
= _flags_save_DATA_BLOB
;
285 NDR_CHECK(ndr_pull_subcontext_start(ndr
, &_ndr_sid
, 0, r
->sid_size
));
286 NDR_CHECK(ndr_pull_dom_sid0(_ndr_sid
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sid
));
287 NDR_CHECK(ndr_pull_subcontext_end(ndr
, _ndr_sid
, 0, r
->sid_size
));
291 NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, &r
->nt_version
));
292 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lmnt_token
));
293 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lm20_token
));
295 if (ndr_flags
& NDR_BUFFERS
) {
297 return NDR_ERR_SUCCESS
;
300 /* Manually modified to only push some parts of the structure if certain flags are set */
301 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
)
304 uint32_t _flags_save_STRUCT
= ndr
->flags
;
305 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_NOALIGN
);
306 if (ndr_flags
& NDR_SCALARS
) {
307 NDR_CHECK(ndr_push_align(ndr
, 4));
308 NDR_CHECK(ndr_push_netlogon_command(ndr
, NDR_SCALARS
, r
->command
));
309 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->sbz
));
310 NDR_CHECK(ndr_push_nbt_server_type(ndr
, NDR_SCALARS
, r
->server_type
));
311 NDR_CHECK(ndr_push_GUID(ndr
, NDR_SCALARS
, &r
->domain_uuid
));
312 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->forest
));
313 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->dns_domain
));
314 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->pdc_dns_name
));
315 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->domain_name
));
316 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->pdc_name
));
317 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->user_name
));
318 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->server_site
));
319 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->client_site
));
320 if (r
->nt_version
& NETLOGON_NT_VERSION_5EX_WITH_IP
) {
321 NDR_CHECK(ndr_push_uint8(ndr
, NDR_SCALARS
, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
323 struct ndr_push
*_ndr_sockaddr
;
324 NDR_CHECK(ndr_push_subcontext_start(ndr
, &_ndr_sockaddr
, 0, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
325 NDR_CHECK(ndr_push_nbt_sockaddr(_ndr_sockaddr
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sockaddr
));
326 NDR_CHECK(ndr_push_subcontext_end(ndr
, _ndr_sockaddr
, 0, ndr_size_nbt_sockaddr(&r
->sockaddr
, ndr
->flags
)));
329 if (r
->nt_version
& NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
) {
330 NDR_CHECK(ndr_push_nbt_string(ndr
, NDR_SCALARS
, r
->next_closest_site
));
332 NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, r
->nt_version
));
333 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lmnt_token
));
334 NDR_CHECK(ndr_push_uint16(ndr
, NDR_SCALARS
, r
->lm20_token
));
336 if (ndr_flags
& NDR_BUFFERS
) {
337 NDR_CHECK(ndr_push_GUID(ndr
, NDR_BUFFERS
, &r
->domain_uuid
));
339 ndr
->flags
= _flags_save_STRUCT
;
341 return NDR_ERR_SUCCESS
;
344 /* Manually modified to only pull some parts of the structure if certain flags provided */
345 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
,
346 uint32_t nt_version_flags
)
349 uint32_t _flags_save_STRUCT
= ndr
->flags
;
351 ndr_set_flags(&ndr
->flags
, LIBNDR_FLAG_NOALIGN
);
352 if (ndr_flags
& NDR_SCALARS
) {
353 NDR_CHECK(ndr_pull_align(ndr
, 4));
354 NDR_CHECK(ndr_pull_netlogon_command(ndr
, NDR_SCALARS
, &r
->command
));
355 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->sbz
));
356 NDR_CHECK(ndr_pull_nbt_server_type(ndr
, NDR_SCALARS
, &r
->server_type
));
357 NDR_CHECK(ndr_pull_GUID(ndr
, NDR_SCALARS
, &r
->domain_uuid
));
358 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->forest
));
359 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->dns_domain
));
360 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->pdc_dns_name
));
361 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->domain_name
));
362 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->pdc_name
));
363 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->user_name
));
364 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->server_site
));
365 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->client_site
));
366 if (nt_version_flags
& NETLOGON_NT_VERSION_5EX_WITH_IP
) {
367 NDR_CHECK(ndr_pull_uint8(ndr
, NDR_SCALARS
, &r
->sockaddr_size
));
369 struct ndr_pull
*_ndr_sockaddr
;
370 NDR_CHECK(ndr_pull_subcontext_start(ndr
, &_ndr_sockaddr
, 0, r
->sockaddr_size
));
371 NDR_CHECK(ndr_pull_nbt_sockaddr(_ndr_sockaddr
, NDR_SCALARS
|NDR_BUFFERS
, &r
->sockaddr
));
372 NDR_CHECK(ndr_pull_subcontext_end(ndr
, _ndr_sockaddr
, 0, r
->sockaddr_size
));
375 if (nt_version_flags
& NETLOGON_NT_VERSION_WITH_CLOSEST_SITE
) {
376 NDR_CHECK(ndr_pull_nbt_string(ndr
, NDR_SCALARS
, &r
->next_closest_site
));
378 NDR_CHECK(ndr_pull_netlogon_nt_version_flags(ndr
, NDR_SCALARS
, &r
->nt_version
));
379 if (r
->nt_version
!= nt_version_flags
) {
380 return NDR_ERR_VALIDATE
;
382 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lmnt_token
));
383 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &r
->lm20_token
));
385 if (ndr_flags
& NDR_BUFFERS
) {
386 NDR_CHECK(ndr_pull_GUID(ndr
, NDR_BUFFERS
, &r
->domain_uuid
));
388 ndr
->flags
= _flags_save_STRUCT
;
390 return NDR_ERR_SUCCESS
;
393 _PUBLIC_
enum ndr_err_code
ndr_push_netlogon_samlogon_response(struct ndr_push
*ndr
, int ndr_flags
, const struct netlogon_samlogon_response
*r
)
395 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
396 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40(
397 ndr
, ndr_flags
, &r
->data
.nt4
));
398 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
399 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
400 ndr
, ndr_flags
, &r
->data
.nt5_ex
));
401 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
402 NDR_CHECK(ndr_push_NETLOGON_SAM_LOGON_RESPONSE(
403 ndr
, ndr_flags
, &r
->data
.nt5
));
405 return NDR_ERR_BAD_SWITCH
;
408 return NDR_ERR_SUCCESS
;
411 _PUBLIC_
enum ndr_err_code
ndr_pull_netlogon_samlogon_response(struct ndr_pull
*ndr
, int ndr_flags
, struct netlogon_samlogon_response
*r
)
413 if (ndr
->data_size
< 8) {
414 return NDR_ERR_BUFSIZE
;
418 if (SVAL(ndr
->data
, ndr
->data_size
- 4) != 0xffff) {
419 return NDR_ERR_TOKEN
;
422 if (SVAL(ndr
->data
, ndr
->data_size
- 2) != 0xffff) {
423 return NDR_ERR_TOKEN
;
426 r
->ntver
= IVAL(ndr
->data
, ndr
->data_size
- 8);
428 if (r
->ntver
== NETLOGON_NT_VERSION_1
) {
429 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40(
430 ndr
, ndr_flags
, &r
->data
.nt4
));
431 } else if (r
->ntver
& NETLOGON_NT_VERSION_5EX
) {
432 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
433 ndr
, ndr_flags
, &r
->data
.nt5_ex
, r
->ntver
));
434 if (ndr
->offset
< ndr
->data_size
) {
435 return ndr_pull_error(ndr
, NDR_ERR_UNREAD_BYTES
,
436 "not all bytes consumed ofs[%u] size[%u]",
437 ndr
->offset
, ndr
->data_size
);
439 } else if (r
->ntver
& NETLOGON_NT_VERSION_5
) {
440 NDR_CHECK(ndr_pull_NETLOGON_SAM_LOGON_RESPONSE(
441 ndr
, ndr_flags
, &r
->data
.nt5
));
443 return NDR_ERR_BAD_SWITCH
;
446 return NDR_ERR_SUCCESS
;